【问题标题】:match.call with function call suppliedmatch.call 提供了函数调用
【发布时间】:2018-12-01 20:34:12
【问题描述】:

我想捕获所有参数和值并返回一个命名列表。在提供的值是函数调用的情况下,我遇到了麻烦。

下面产生了一个“call”类的对象,这对我来说很不方便,因为我想在它上面调用paste

fun1 = function(a = 1) as.list(match.call()[-1])
value1 = fun1(a = letters[1:2])
class(value1[[1]])
[1] "call"
paste(value1[[1]], collapse = " - ")
[1] "[ - letters - 1:2" #not useful to me

作为一种解决方法,我可以调用eval 来获取由c 创建的字符向量(lapply 函数用于说明当有多个参数时,将在所有参数上调用eval):

fun2 = function(a = 1) lapply(as.list(match.call()[-1]), eval)
value2 = fun2(a = letters[1:2])
class(value2[[1]])
[1] "character"
paste(value2[[1]], collapse = " - ")
[1] "a - b" #that's what I want

有没有更好的方法来做到这一点?在一堆事情上调用 eval 只是为了获取值对我来说似乎有点奇怪。

编辑:这背后的想法是我想将参数列表传递给原始函数中的函数(该函数接受其参数之一的命名列表)。我想捕获用户提供的值和默认值(用于用户未提供任何内容的参数)。

我在其他地方了解到,我可以通过 match.callformals 的组合获得所有这些。但是,假设我需要将其传递给httr::GET 函数的query 参数,并在我这样做之前对其进行一些处理(例如在“a”和“b”之间添加“-”)。然后我最终得到类似“[ - 字母 - 1:2”而不是“a - b”。

我感觉如果答案是使用eval,那么我可能问错了问题。

【问题讨论】:

  • 如果您想要评估的参数,为什么要使用 match.call?这似乎完全没有必要。
  • @Roland 感谢您的评论!我试图在原帖中澄清。我觉得我问错了问题,但目前无法找出正确的问题。
  • 我还是不明白。是什么阻止您在函数中使用类似 list(a) 的东西?如有必要,可能与省略号结合使用?

标签: r


【解决方案1】:

我感觉到您正在寻找更通用的东西,所以不确定这是否完全是您正在寻找的东西,但它更简单并且可以为您提供所需的结果。这里的关键部分是 do.call()

fun1 = function(a = 1) {
  L1 <- as.list(match.call())
  do.call(paste0, list(L1$a, sep="", collapse=" - "))
}

value1 = fun1(a = letters[1:2])

【讨论】:

  • 嗯,是的,好老do.call。感觉像是一个解决方案。让我回复你。
【解决方案2】:

好吧,我认为您需要决定代码的哪些部分需要评估,哪些不需要。
从您的示例中并不完全清楚您想要多通用,但是您的示例问题可以通过一个简单的 list() 来解决,您只需要一个自定义函数来提供默认值:

myfun <- function(a=1) list(a=a)
value <- myfun(a=letters[1:2]))
paste(value[[1]], collapse = " - ")
# Basically: value <- list(a=letters[1:2])), or paste(letters[1:2], collapse= " - ")

通常,您使用不带任何参数的 match.call() 来找出调用函数的方式。有时了解是否调用了 fun(a=c('a', 'b')) 或 fun1(a = letters[1:2]) 很有用,因此 match.call 会告诉您这一点,而无需评估任何内容。

所以如果你想对你的参数做一些实际的事情,只需直接调用它们,然后你可以将它们传递给另一个函数

mypaste <- function(..., sep=' -CustomSep- ', collapse=' -Mycollapse- ', prefix='Value:') {
  if(length(list(...))>0) {
    paste(prefix, ..., sep=sep, collapse=collapse)
  } else {
    text <- character(0)
  }
}

此功能只是粘贴的一种变体,但您可以根据需要进行扩展。

我的印象是,您想要一个一般情况,将您的参数与另一个函数的参数相匹配,但要回答这个问题,我需要更多地了解您到底想要完成什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2020-09-30
    • 2023-02-03
    相关资源
    最近更新 更多