I'm using the following construct in a package,
## 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
but I've just been bitten by the fact that it won't work if the functions are in a different (local) frame,
## 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"
I've tried passing envir=parent.frame(2)
to do.call()
(doesn't work); frankly the help page of ?parent.frame
goes way over my head. Any hint for a more robust use of do.call?
Note that the list of functions comes as a character vector, passed from another piece of code; I prefer not to pass the functions directly.
Edit: one more twist... I thought I'd illustrated the right problem with my toy example, but the actual code I'm using is slightly different, in the sense that I'm calling fun_wrap1
within a separate function. The proposed solutions fail in this context.
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"
(and the same happens with the match.fun
approach)
I can get it to work by passing an optional environment to 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()
and that's hopefully it.
fun_wrap1 <- function(funs, envir = parent.frame()) { lapply(funs, do.call, args=list(x=3), envir=envir) }
Thefoo
function can stay as it is. – Plinthenvironment()
infoo
. – Plinth