R 计算函数参数的方式很神奇

Magic in the way R evaluates function arguments

考虑以下 R 代码:

y1 <- dataset %>% dplyr::filter(W == 1) 

这行得通,但这里似乎有些神奇。通常,当我们有像foo(bar)这样的表达式时,我们应该可以这样做:

baz <= bar
foo(baz)

但是,在提供的代码片段中,我们无法在 dplyr::filter() 之外计算 W == 1W 不是定义的变量。

怎么回事?

dplyr 使用称为 Non-standard Evaluation (NSE) 的概念使其函数可以访问数据框参数中的列,而无需引用或使用 dataframe$column 语法。基本上:

[Non-standard evaluation] is a catch-all term that means they don’t follow the usual R rules of evaluation. Instead, they capture the expression that you typed and evaluate it in a custom way.1

在这种情况下,自定义评估采用给定 dplyr::filter 的参数并解析它们,以便 W 可用于引用 dataset$W。然后您不能获取该变量并在其他地方使用它的原因是 NSE 仅应用于函数的范围。


NSE 做出权衡:修改作用域的函数不太安全and/or 在您构建使用函数修改其他函数的程序的编程中不可用:

This is an example of the general tension between functions that are designed for interactive use and functions that are safe to program with. A function that uses substitute() might reduce typing, but it can be difficult to call from another function.2

例如,如果您想编写一个使用相同代码的函数,但将 W == 1 换成 W == 0(或一些完全不同的过滤器),NSE 会使实现变得更加困难完成。

2017 年,tidyverse 在 tidy evaluation 中开始为此构建解决方案。