将 match.call() 与 mapply 一起使用

Using match.call() with mapply

我有一个函数,它基本上从参数中输出一个布尔条件作为字符串(函数的细节在这里无关紧要)

makeClause <-function(Sex=c("NA", "male", "female"),
        SmokingHx=c("NA", "current", "former", "never"),
        conjunction=c("&", "|")) {
    arglist = as.list(match.call())
    return(arglist)
}

我有一个包含所有输入参数组合的数据框,如:

       Sex SmokingHx conjunction
1       NA        NA           &
2     Male        NA           &
...

我是这样得到的:

combinations = expand.grid(Sex=c("NA", "male", "female"), 
                           SmokingHx=c("NA", "current", "former", "never"), 
                           conjunction=c("&", "|"),
                           stringsAsFactors=FALSE)

然后我用 mapply 调用 makeClause:

mapply(makeClause, Sex=combinations$Sex,SmokingHx=combinations$SmokingHx, conjunction=combinations$conjunction)

查看 arglist 变量我得到:

$Sex
dots[[1L]][[1L]]

$SmokingHx
dots[[2L]][[1L]]

$conjunction
dots[[4L]][[1L]]

如果我调用 as.list(environment()) 而不是 as.list(match.call()),我会得到:

$Sex
[1] "male"

$SmokingHx
[1] "NA"

$conjunction
dots[[4L]][[1L]] # notice this is the only one for which I don't get the actual string

所以我有两个问题:

  1. 您能否解释导致将其作为参数值而不是实际字符串值的 R 内部机制?
  2. 我该如何解决这个问题,即获取参数列表中的字符串值?

谢谢

为什么会这样:

match.call 将引用的调用捕获为语言对象。 dots 业务是 mapply 用来调用您的函数的业务,因此 match.call 的 return 值是正确的。它只是匹配 mapply 为您的函数构建的调用和 return 引用的(即未计算的)值。在内部 mapply 正在做这样的事情(虽然不是真的,因为它是内部 C 代码):

dots <- list(...)
call <- list()
for(j in seq_along(dots[[1]])) {
  for(i in seq_along(dots)) call[[i]] <- bquote(dots[[.(j)]][[.(i)]])
  eval(as.call(c(quote(FUN), call))))
}

如果您查看 as.call(c(FUN, call)),您会看到类似 FUN(dots[[1L]][[1L]], dots[[1L]][[2L]], dots[[1L]][[3L]]) 的内容,这有助于解释为什么您会得到现在的结果。

如何解决:

您似乎想要您的论点的。您可以评估从 match.call 中获得的结果,或者更简单,只需使用:

list(Sex, SmokingHx, conjunction)

如果您想要获取函数的所有参数而无需知道它们的名称,您可以这样做:

mget(names(formals()))

尝试(为清楚起见简化乐趣):

makeClause <-function(Sex, SmokingHx, conjunction) mget(names(formals()))

with(combinations, t(mapply(makeClause, Sex, SmokingHx, conjunction)))

产生:

       Sex      SmokingHx conjunction
NA     "NA"     "NA"      "&"        
male   "male"   "NA"      "&"        
female "female" "NA"      "&"        
NA     "NA"     "current" "&"        
male   "male"   "current" "&"        
female "female" "current" "&"      
... further rows omitted