首页 文章

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

提问于
浏览
3

所以在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的对象,因此无法计算 . 但是,如果在全球环境中设置了一个,那么可能会发生更多令人困惑的事情:

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

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

  • 作为一个承诺,在解密的定义中的条件是懒惰的评估?调用时为什么不进行评估:scramble(subset2(x,condition))

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

scramble(subset2(x,(condition)))

现在迫使评估条件 . 这里的规则是什么?

  • 当哈德利说“当我们评估condition_call时,它还评估条件”,什么是“它”?他是否意味着“eval”触发了某种内部或次要评估,试图解决承诺“条件”?这发生在哪里?即,R试图用什么环境来找出“条件”的 Value 是什么?

  • 所以错误“找不到对象”不是由于下面的调用中的“x”或“parent.frame()”,而是在其他地方?我完全糊涂了 .

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

1 回答

  • 3

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

    Non standard evaluation from another function in R

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

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

相关问题