gpt4 book ai didi

全局环境中的递归评估

转载 作者:行者123 更新时间:2023-12-04 07:53:53 25 4
gpt4 key购买 nike

我很难理解为什么我尝试递归应用 eval , 使用 rapply , 不管用。

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

# 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我把列表弄平了,可以 eval使用 lapply .
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在全局环境中?

最佳答案

来自 rapply 的文档说明:

The semantics differ in detail from lapply: in particular the arguments are evaluated before calling the C code.



请尝试以下操作以了解它们的含义:
rapply(list(quote(stop("error"))), function(x) x)
# Error in (function (x) : error
lapply(list(quote(stop("error"))), function(x) x)
# [[1]]
# stop("error")

您可以尝试将其作为解决方法:
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 在全局环境中被评估,而不是 x <- x + 9 )。通过使用 substitute我们能够挽救原始表达。

关于全局环境中的递归评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22558887/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com