Używam następujących skonstruować w opakowaniu,do.call określić środowisko wewnątrz funkcji
## 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
ale ja właśnie został ugryziony przez fakt, że to nie będzie działać, jeśli te funkcje są w sposób różne (lokalny) ramki
## 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"
próbowałem przechodzącą envir=parent.frame(2)
do do.call()
(nie działa); szczerze strona pomocy ?parent.frame
przechodzi przez moją głowę. Jakąkolwiek podpowiedź na bardziej niezawodne użycie do.call?
Zauważ, że lista funkcji pochodzi z wektora znaków, przekazywana z innego fragmentu kodu; Wolę nie przekazywać bezpośrednio funkcji.
Edit: jeden skręt ... Myślałam, że ilustruje właściwą problem z moim przykładzie zabawek, ale rzeczywisty kod używam jest nieco inny, w tym sensie, że dzwonię fun_wrap1
zasięgu oddzielna funkcja. Proponowane rozwiązania zawodzą w tym kontekście.
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"
(i to samo dzieje się z podejściem match.fun
)
mogę zmusić go do pracy przez przekazanie opcjonalnego środowisko 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()
i mam nadzieję, że to ona.
Przepraszam za ciągłe zmiany, nie udało mi się poprawnie zidentyfikować celu, kiedy napisałem pierwszą iterację. – baptiste
W poprawionym przykładzie, który się nie powiedzie, nowa funkcja powinna zostać zmieniona na: 'fun_wrap1 <- function (funs, envir = parent.frame()) { lapply (funs, do.call, args = list (x = 3) , envir = envir) } 'Funkcja' foo' może pozostać taka jaka jest. –
Dzięki, zmieniłem go zgodnie z twoją radą. – baptiste