В своей очевидной наивности я предположил, что когда кто-то вызывает eval
и указывает среду (envir
), выражение (expr
) оценивается в этой среде.
Однако :-)
Это работает, как и ожидалось:
xx <- 10
nn <- 20
exprs <- binom.test(x=xx,n=nn)
eval(exprs);
По умолчанию eval
вычисляет в parent.frame()
, что показывает справка: [t] родительский кадр оценки функцииэто среда, в которой была вызвана функция.
Итак, в приведенном выше примере это глобальная среда, в которой действительно определены xx
и nn
.Пока все хорошо.
newEnv <- new.env();
assign('xxx', 10, envir = newEnv);
assign('nnn', 30, envir = newEnv);
exprs2 <- expression(binom.test(x=xxx,n=nnn));
eval(exprs2, envir=newEnv);
Это также работает, как и ожидалось;xxx
и nnn
определены в среде newEnv
, и binom.test
оценивается в этой среде.
Теперь мы заключаем это в функцию (ту, которую я пытаюсь построить - яя собираю его с помощью пакета pwr
, но для этого примера я использую binom.test
, потому что это база R и он все еще не работает: -)
loopFunction <- function(expr,
...) {
### Get all 'dots' in a named list
arguments <- list(...);
argNames <- names(arguments);
if (any(length(tail(arguments, -2) > 1))) {
stop("Only the first two arguments may have length > 1!");
}
for (esIndex in seq_along(arguments[[1]])) {
for (pwrIndex in seq_along(arguments[[2]])) {
tempEnvironment <-
new.env();
assign(argNames[1], arguments[[1]][esIndex],
envir = tempEnvironment);
assign(argNames[2], arguments[[2]][pwrIndex],
envir = tempEnvironment);
if (length(arguments) > 2) {
for (i in 3:length(arguments)) {
assign(argNames[i], arguments[[i]],
envir = tempEnvironment);
}
}
print(argNames);
print(as.list(tempEnvironment));
print(ls(tempEnvironment));
print(get('x', envir=tempEnvironment));
print(get('n', envir=tempEnvironment));
return(eval(expr = expression(expr),
envir = tempEnvironment)$estimate);
}
}
}
При запуске этого выget:
loopFunction(binom.test(x=x,n=n), x=c(10,20), n=c(30, 100));
#> [1] "x" "n"
#> $x
#> [1] 10
#>
#> $n
#> [1] 30
#>
#> [1] "n" "x"
#> [1] 10
#> [1] 30
#> Error in binom.test(x = x, n = n): object 'x' not found
Итак, эта ошибка ставит меня в тупик.ясно, что x
и n
существуют в tempEnvironment
;и tempEnvironment
передается eval
.
Почему это внезапно перестает работать?Это работает по-другому внутри функций?Я что-то упускаю из виду?