非标准评估,高级R书中的混乱

时间:2015-07-17 15:52:25

标签: r promise lazy-evaluation evaluation standard-evaluation

所以在Hadley的高级R书中,有一个使用替换的问题的例子,这里是代码的摘录:

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_call时,它还会评估条件,其值为a> = 4.但是,由于在父环境中没有名为a的对象,因此无法计算。但是,如果在全球环境中设置了一个,就会发生更加混乱的事情:

在本书的上一段中,有几件事让我感到困惑。

  1. 句子&#34; condition_call包含表达式条件&#34;。符号&#34;条件&#34;在函数subset2中用作形式参数,也用于scramble中的实参数(subset2(x,condition))。我猜他提到了这个真实/调用的参数&#34;条件&#34;,对吗?

  2. 作为一个承诺,在解密的定义中的条件是懒惰的评估?为什么在调用时不评估它: 争夺(subset2(x,condition))

  3. 换句话说,如何通过查看代码来了解是否评估了承诺?例如,如果我理解正确,如果我将代码更改为以下内容:

    scramble(subset2(x,(condition))) 
    

    现在强制评估条件。这里的规则是什么?

    1. 当Hadley说&#34;当我们评估condition_call时,它还评估条件&#34;,什么是#34;它&#34;?他的意思是&#34; eval&#34;引发某种内部或次要评估,试图解决承诺&#34;条件&#34;?这发生在哪里?即,R试图用什么来找出&#34; condition&#34;的价值是什么?

    2. 所以错误&#34;对象a找不到&#34;不是因为&#34; x&#34;或&#34; parent.frame()&#34;在下面的调用中,而是在其他地方?我完全糊涂了。

      r&lt; - eval(condition_call,x,parent.frame())

1 个答案:

答案 0 :(得分:3)

我无法发表评论,所以我会将此作为答案发布。一切都只是改变:

Non standard evaluation from another function in R

基本上发生的事情是在sample_df调用环境中,该函数将查找“condition”而不是“a&gt; = 4”。由于它找不到它,它向上移动然后在调用环境中找到条件;子解密执行环境(这是因为subset2(x,condition)是在此环境中创建的一个承诺),它找到一个&gt; = 4。

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