哪里如果有记录了非标准评估的危险?

问题描述

许多 R 函数具有非标准评估,例如withsubsettransform 包含如下警告:

对于交互式使用,这是非常有效且易于阅读的。然而,对于编程,即在一个函数中,需要更加小心,通常应该避免使用with(),因为例如,数据中的变量可能会意外覆盖局部变量,请参阅参考。
(引用自 with 的文档,其他内容的信息较少)

“引用”是 this 2003 article。坦率地说,我没有看到它的相关性。它在第 6 节中提到了“数据中的变量可能会意外覆盖局部变量”这一点,但它只是这样做 - 提及它。据我所知,该文章中没有任何内容告诉您警告告诉您检查参考资料尚未告诉您的任何内容

搜索the R Manuals,甚至在 3500 页的参考索引中搜索了术语“非标准”,但除了我已经提到的内容之外,我什么也没找到。我真的以为它会在 the language definition 中,但我已经阅读了整篇文章却没有找到。我得到的最接近的是 the section that covers the substitute function,我碰巧知道很多非标准评估的函数都依赖于此。

至于我确信找不到帮助的任何其他地方,我已经从头到尾阅读了 the R FAQAn Introduction to R。 R 常见问题解答多次提到 evalsubstitute,但与此处无关。唯一值得注意的部分是 here,它也建议检查 deriv 的文档,但我发现那里没有任何用处。

那么,R 是否有任何官方部分实际上记录了非标准评估的危险?我觉得很奇怪,R 的部分文档会告诉我要小心处理某些事情,而没有提供任何告诉我如何去做的地方。不可否认,需要照顾。例如,使用非标准求值函数Advanced R shows several ways 可能会导致问题。 I have paid 之前的这种粗心大意,不难发现 excellent answers评论中充满了关于非标准评估的警告。

解决方法

我猜 R 语言定义的第 6.3 "More on Evaluation" 部分说明了整个问题。

另一个经常发生的情况是在列表或数据框中求值。例如,当给出数据参数时,这与 model.frame 函数有关。通常,模型公式的项需要在数据中进行评估,但它们偶尔也可能包含对 model.frame 调用方中项的引用。这有时与模拟研究有关。因此,为此目的,不仅需要对列表中的表达式求值,而且还需要指定一个外壳,如果该变量不在列表中,则搜索将继续到该外壳中。因此,调用的形式为 eval(expr,data,sys.frame(sys.parent()))

然后是文字似乎在“警告”读者的特定部分:

请注意,给定环境中的求值实际上可能会改变该环境,最明显的是涉及赋值运算符的情况,例如 eval(quote(total <- 0),environment(robert$balance)) # rob Rob。在列表中评估时也是如此,但原始列表不会改变,因为一个人确实在处理副本。

也许它应该改进,因为它绝对不会直接接近非标准评估,可以说。

,

(作为答案发布,因为这对于评论来说有点太长了。)

我不知道记录危险的具体位置,但根据我的个人经验,在使用 NSE 时需要牢记两个重要的警告:

  1. substitute() does not work correctly in nested functions,当试图用使用 substitute() 的函数做复杂的事情时会导致问题。示例包括 glm()coxph()

  2. 如果使用 rlang,运算符 !! 的结果为 immediate evaluation of its operand w.r.t. the expression as a whole。如果表达式包含将在计算表达式的其他部分时定义的变量,这可能会导致模糊的“未找到变量”错误。

除了这两个警告之外,我通常发现 NSE 非常强大。如果您使用 rlang,则尤其如此,这对标准化 NSE 功能大有帮助。话虽如此,我个人的建议是仅在必要时使用 NSE,并尽可能坚持标准评估 (SE)。虽然 NSE 可能非常强大,但它生成的代码可能难以阅读、理解和维护。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...