使用match.call()和mapply

时间:2015-02-26 21:56:55

标签: r 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)

我用makeClause致电mapply

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(match.call())而是拨打as.list(environment())我会改为:

$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. 如何解决这个问题,即在参数列表中获取字符串值?
  3. 由于

1 个答案:

答案 0 :(得分:3)

为什么会发生这种情况:

match.call将引用的调用捕获为语言对象。 dots业务是mapply用于调用您的函数的业务,因此match.call的返回值是正确的。它只是匹配mapply为您的函数构造的调用并返回引用的(即未评估的)值。内部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