非标准评估,在高级R书籍中的混淆

3

在Hadley的高级R书中,有一个使用substitute的问题示例,以下是代码摘录:

subset2 <- function(x, condition) {
condition_call <- substitute(condition)
r <- eval(condition_call, x, parent.frame())
x[r, ]
}

scramble <- function(x) x[sample(nrow(x)), ]

subscramble <- function(x, condition) {
 scramble(subset2(x, condition))
}


subscramble(sample_df, a >= 4)
# Error in eval(expr, envir, enclos) : object 'a' not found
traceback()
#> 5: eval(expr, envir, enclos)
#> 4: eval(condition_call, x, parent.frame()) at #3
#> 3: subset2(x, condition) at #1
#> 2: scramble(subset2(x, condition)) at #2
#> 1: subscramble(sample_df, a >= 4)

你能看出问题在哪里吗?condition_call包含表达式condition。当我们评估condition_call时,它也会评估条件,即a >= 4。但是,由于没有名为a的对象在父环境中,因此无法计算。但是,如果在全局环境中设置了a,更令人困惑的事情可能会发生:
上述书中的段落有几个让我感到困惑的地方。
1.句子“condition_call包含表达式condition”。符号“condition”用作函数subset2中的形式参数,并在scramble(subset2(x,condition))的实际参数中使用。我想他指的是这个实际/调用参数“condition”,对吗?
2.作为promise,定义subscramble中的条件是否惰性评估?为什么在调用scramble(subset2(x,condition))时没有进行评估?
换句话说,通过查看代码,如何知道承诺是否已经被评估?例如,如果我正确理解它,如果我将代码更改为以下内容:
scramble(subset2(x,(condition))) 

现在强制对条件进行求值。那么这里的规则是什么?

  1. 当Hadley说“当我们评估condition_call时,它也会评估condition”,“它”是指什么?他是否意味着“eval”触发了某种内部或次要评估,试图解析承诺“条件”?这发生在哪里?也就是说,R试图使用什么环境来查找“条件”的值?

  2. 因此,“对象a未找到”的错误不是由下面的调用中的“x”或“parent.frame()”引起的,而是由其他地方引起的吗?我完全困惑了。

    r <- eval(condition_call, x, parent.frame())

1个回答

3

我无法发表评论,所以我将其作为答案发布。所有内容都只是重新解释了以下内容:

从R中的另一个函数进行非标准评估

基本上,在sample_df调用环境中,该函数将寻找“condition”而不是“a>=4”。由于它找不到这个条件,因此它向上移动,然后在调用环境中找到条件;子程序执行环境(这是因为subset2(x, condition)是在此环境中创建的承诺),在那里它找到了a>=4。

现在需要找到a,但我们已经离开了sample_df数据环境,因此它在全局环境中搜索,如果a在全局环境中定义,则会导致奇怪的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接