R - 评估环境中的嵌套函数

时间:2013-07-18 19:31:37

标签: r function eval

我试图以沙箱方式运行一大块R代码,方法是将所有必要的依赖项(函数和数据)加载到新环境中并评估该环境中的表达式。但是,我在调用环境中的其他函数时遇到了麻烦。这是一个简单的例子:

jobenv <- new.env(parent=globalenv())
assign("f1", function(x) x*2, envir=jobenv)
assign("f2", function(y) f1(y) + 1, envir=jobenv)
expr <- quote(f2(3))

eval上使用expr失败,因为f2无法找到f1

> eval(expr, envir=jobenv)
Error in f2(3) : could not find function "f1"

而明确附加环境有效

> attach(jobenv)
> eval(expr)
[1] 7

我可能错过了一些明显的东西,但我找不到有效的eval调用的任何排列。有没有办法在不附加环境的情况下获得相同的效果?

2 个答案:

答案 0 :(得分:7)

有很多方法可以做到这一点,但我有点像这样:

jobenv <- new.env(parent=globalenv())

local({
    f1 <- function(x) x*2
    f2 <- function(y) f1(y) + 1
}, envir=jobenv)

## Check that it works
ls(jobenv)
# [1] "f1" "f2"
local(f2(3), envir=jobenv)
# [1] 7
eval(quote(f2(3)), envir=jobenv)
# [1] 7

答案 1 :(得分:4)

范围是在创建函数时定义的,而不是在调用函数时定义的。请参阅section 10.7 of the Introduction to R手册。

这对我来说似乎有点奇怪,但即使你完全避免使用assign而只是使用$<-,你也会得到同样的行为。

jobenv <- new.env(parent=globalenv())
jobenv$f1 <- function(x) x*2
jobenv$f2 <- function(y) f1(y) + 1
expr <- quote(f2(3))
eval(expr, envir=jobenv)

这似乎是因为f1f2的封闭环境是全球环境。我原以为它是jobenv

> environment(jobenv$f1)
<environment: R_GlobalEnv>
> environment(jobenv$f2)
<environment: R_GlobalEnv>

一个解决方案是明确设置每个函数的环境......但必须有一个更简单的方法。

> environment(jobenv$f1) <- jobenv
> environment(jobenv$f2) <- jobenv
> eval(expr, envir=jobenv)
[1] 7