首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >全局环境中的递归环境

全局环境中的递归环境
EN

Stack Overflow用户
提问于 2014-03-21 12:32:28
回答 1查看 666关注 0票数 8

我很难理解为什么我使用eval递归应用rapply的尝试不起作用。

我有一个嵌套的表达式列表:

代码语言:javascript
复制
# Some expressions   
expr1 <- quote(x <- x + 9)
expr2 <- quote(x <- x/2)
expr3 <- quote(x <- x + 3)
expr4 <- quote(x <- x * 3)

# Generate a nested list of expressions
exprs <- list(expr1, list(expr2, expr3), expr4)

# Initialize x, and attempt to eval the expressions
x <- 1
rapply(exprs, eval, envir = globalenv())
# Returns: [1] 10  5  8 24, but x is not changed.

递归显然起作用了,但它没有像我指定的那样计算全局环境中的表达式。基于this answer,我将列表扁平化,并可以使用lapply实现eval

代码语言:javascript
复制
flatten <- function(x) {
  repeat {
    if(!any(vapply(x, is.list, logical(1)))) return(x)
    x <- Reduce(c, x)
  }
}

# Both change x to 24 in the global env, like desired.
lapply(flatten(exprs), eval, envir = globalenv())
lapply(flatten(exprs), eval, envir = parent.frame())

据我所知,rapply/lapply在他们自己的环境中计算,就像任何其他函数一样,然后返回一个值。我可以指定全局环境或父框架(因为lapply的父框架应该是被称为全局环境的环境--这里是全局环境),这是有意义的。

按照这一逻辑,我期望使用rapply指定全局环境才能工作。指定父框架应该会失败(它确实失败),因为我假设嵌套在rapply内部的调用在最初对rapply的调用所创建的环境中得到评估。

我在这里错过了什么?为什么rapply调用不改变全局环境中的x

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-21 12:54:39

rapply文档中的说明

语义与lapply在细节上有所不同:特别是,在调用C代码之前对参数进行了计算。

试着看一看它们的含义:

代码语言:javascript
复制
rapply(list(quote(stop("error"))), function(x) x)
# Error in (function (x)  : error
lapply(list(quote(stop("error"))), function(x) x)
# [[1]]
# stop("error")

您可以尝试将此作为解决方法:

代码语言:javascript
复制
rapply(exprs, evalq, envir = globalenv())  # updated with Hadley's equivalent but cleaner version.
# [1] 10  5  8 24
x
# [1] 24

正如您注意到的,x是在rapply环境中进行计算的,这就是为什么结果是有意义的,但是实际的eval语句不是原始表达式的,而是结果的(即在第一次迭代中,10在全局env中得到计算,而不是x <- x + 9)。通过使用substitute,我们能够挽救原始表达式。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22558887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档