R:为什么eval在parent.frame()中默认评估?

时间:2014-03-31 16:36:18

标签: r scope

我试图使用eval来评估函数中的某些表达式,但是在尝试查找函数作用域中定义的对象时会遇到错误。

我意识到这是因为eval的默认环境是parent.frame()。有这么好的理由吗?我希望它与assign相同,即当前的环境。

以下是一个例子(根据Gabor的要求):

fnFoo = function() {
    # assign 10 variables
    for(i in 1:10) assign(paste('v', i, sep = ''), rnorm(10))

    # find the variables by name and evaluate them
    Map(sum, lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)), eval))
}

# test that eval is unable to find a variable  declared in the function scope
fnFoo()

但是,将功能更改为

fnFoo = function() {
    # assign 10 variables
    for(i in 1:10) assign(paste('v', i, sep = ''), rnorm(10))

    # find the variables by name and evaluate them
    # Map(sum, lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)), eval))
    Map(sum, lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)), function(x) eval(x, envir = environment())))
}

# now it works
fnFoo()

作品。

感谢。

1 个答案:

答案 0 :(得分:1)

您的问题是,您lapplyeval结合使用时过于聪明。让我们扩展正在发生的事情。

lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)), eval)

相当于

lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)),
   function(x) eval(x))

但是,为function(x) eval(x)创建了一个单独的范围,该范围在其直接环境中不再具有v1v2等。因此,您希望evallapply一起使用正确的环境:

lapply(parse(text = grep('v', ls(envir = environment()), value = TRUE)),
       eval, envir = environment())

顺便说一下,另一种方法是

apply(sapply(grep('v', ls(envir = environment()), value = TRUE), get, envir = environment()), 1, sum)