[英]In R, how do I evaluate an expression in a specific environment within a function?
In my apparent naievety, I assumed that when one calls eval
and specifies an environment ( envir
), the expression ( expr
) is evaluated in that environment. 在我显而易见的情况下,我假设当一个人调用eval
并指定一个环境( envir
)时,表达式( expr
)将在该环境中进行评估。
However :-) 但是:-)
This works as expected: 这按预期工作:
xx <- 10
nn <- 20
exprs <- binom.test(x=xx,n=nn)
eval(exprs);
By default, eval
evaluates in parent.frame()
, which the help reveals is [t]he parent frame of a function evaluation is the environment in which the function was called. 默认情况下, eval
在parent.frame()
eval
值,帮助显示为[t]函数求值的父帧是调用函数的环境。
So in the above example, this is the global environment, where indeed, xx
and nn
are defined. 所以在上面的例子中,这是全局环境,确实定义了xx
和nn
。 So far, so good. 到现在为止还挺好。
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);
This also works as expected; 这也按预期工作; xxx
and nnn
are defined in the newEnv
environment, and binom.test
is evaluated in that environment. xxx
和nnn
的在所定义newEnv
环境, binom.test
在该环境中进行评价。
Now we wrap this in a function (the one I'm trying to build - I'm building it using the pwr
package, but for this example I'm using binom.test
because it's base R and it still doesn't work :-) 现在我们将它包装在一个函数中(我正在尝试构建一个函数 - 我正在使用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);
}
}
}
When running this, you 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
So, that error stumps me. 所以,那个错误让我很难过。 clearly, x
and n
exist in tempEnvironment
; 显然, x
和n
存在于tempEnvironment
; and tempEnvironment
is passed to eval
. 和tempEnvironment
传递给eval
。
Why does this suddenly no longer work? 为什么这突然不再起作用? Does this work differently inside functions? 这在功能内部有何不同? Am I missing something obvious? 我错过了一些明显的东西吗
I am not sure why expression()
doesn't work in this context. 我不确定为什么expression()
在这种情况下不起作用。 However, it works if you write expr
as a string and replace expression(expr)
by parse(text=expr)
: 但是,如果您将expr
编写为字符串并使用parse(text=expr)
替换expression(expr)
,则它可以工作:
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=parse(text=expr), envir =tempEnvironment)$estimate)
}
}
}
loopFunction("binom.test(x, n)", x=10, n=30)
Result: 结果:
> loopFunction("binom.test(x, n)", x=10, n=30)
[1] "x" "n"
$`x`
[1] 10
$n
[1] 30
[1] "n" "x"
[1] 10
[1] 30
probability of success
0.3333333
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.