将 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
所以我有两个问题:
- 您能否解释导致将其作为参数值而不是实际字符串值的 R 内部机制?
- 我该如何解决这个问题,即获取参数列表中的字符串值?
谢谢
为什么会这样:
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
我有一个函数,它基本上从参数中输出一个布尔条件作为字符串(函数的细节在这里无关紧要)
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
所以我有两个问题:
- 您能否解释导致将其作为参数值而不是实际字符串值的 R 内部机制?
- 我该如何解决这个问题,即获取参数列表中的字符串值?
谢谢
为什么会这样:
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