在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)))
现在强制对条件进行求值。那么这里的规则是什么?
当Hadley说“当我们评估condition_call时,它也会评估condition”,“它”是指什么?他是否意味着“eval”触发了某种内部或次要评估,试图解析承诺“条件”?这发生在哪里?也就是说,R试图使用什么环境来查找“条件”的值?
因此,“对象a未找到”的错误不是由下面的调用中的“x”或“parent.frame()”引起的,而是由其他地方引起的吗?我完全困惑了。
r <- eval(condition_call, x, parent.frame())