我在一个包中使用以下构造,
## two functions in the global environment
funa <- function(x) x^2
funb <- function(x) x^3
## called within a function, fine
fun_wrap <- function(){
lapply(c('funa', 'funb'), do.call, list(x=3))
}
fun_wrap()
[[1]]
[1] 9
[[2]]
[1] 27
但我刚刚被这样一个事实所困扰,即如果函数位于不同的(本地)框架中,它将无法工作,
## same construct, but the functions are local
fun_wrap1 <- function(){
funa1 <- function(x) x^2
funb1 <- function(x) x^3
lapply(c('funa1', 'funb1'), do.call, list(x=3))
}
## now it fails
fun_wrap1()
##Error in FUN(c("funa1", "funb1")[[1L]], ...) :
## could not find function "funa1"
我试过传递envir=parent.frame(2)
给do.call()
(不起作用);坦率地说,帮助页面?parent.frame
超出了我的想象。有什么提示可以更强大地使用 do.call 吗?
请注意,函数列表以字符向量的形式出现,从另一段代码传递过来;我不喜欢直接传递函数。
编辑:还有一个转折......我认为我已经用我的玩具示例说明了正确的问题,但我使用的实际代码略有不同,因为我fun_wrap1
在单独的函数中调用。建议的解决方案在这种情况下失败了。
fun_wrap1 <- function(funs){
lapply(funs, do.call, args=list(x=3), envir=environment())
}
foo <- function(){
funa1 <- function(x) x^2
funb1 <- function(x) x^3
fun_wrap1(c('funa1', 'funb1'))
}
foo()
##Error in FUN(c("funa1", "funb1")[[1L]], ...) :
## could not find function "funa1"
(这种match.fun
方法也会发生同样的情况)
我可以通过将可选环境传递给它来使其工作fun_wrap1
,
fun_wrap1 <- function(funs, e=parent.frame()){
lapply(funs, do.call, args=list(x=3), envir=e)
}
foo <- function(){
funa1 <- function(x) x^2
funb1 <- function(x) x^3
fun_wrap1(c('funa1', 'funb1'))
}
foo()
希望就是这样。