考虑以下 R 代码:
y1 <- dataset %>% dplyr::filter(W == 1)
这行得通,但这里似乎有一些魔力。通常,当我们有一个类似的表达式时foo(bar)
,我们应该能够这样做:
baz <= bar
foo(baz)
但是,在提供的代码片段中,我们无法W == 1
在dplyr::filter()
! W
不是定义的变量。
这是怎么回事?
考虑以下 R 代码:
y1 <- dataset %>% dplyr::filter(W == 1)
这行得通,但这里似乎有一些魔力。通常,当我们有一个类似的表达式时foo(bar)
,我们应该能够这样做:
baz <= bar
foo(baz)
但是,在提供的代码片段中,我们无法W == 1
在dplyr::filter()
! W
不是定义的变量。
这是怎么回事?
dplyr 使用称为非标准评估(NSE) 的概念来使数据框参数中的列对其函数可访问,而无需引用或使用dataframe$column
语法。基本上:
[非标准评估] 是一个包罗万象的术语,这意味着它们不遵循通常的 R 评估规则。相反,它们捕获您键入的表达式并以自定义方式对其进行评估。1
在这种情况下,自定义评估接受给定的参数dplyr::filter
,并解析它们,以便W
可以用来引用dataset$W
. 然后您不能将该变量并在其他地方使用它的原因是 NSE 仅适用于函数的范围。
NSE 进行了权衡:修改范围的函数在您正在构建使用函数修改其他函数的程序的编程中不太安全和/或不可用:
这是为交互使用而设计的功能与可安全编程的功能之间普遍紧张的一个示例。使用substitute() 的函数可能会减少输入,但很难从另一个函数调用。2
例如,如果您想编写一个使用相同代码但换成(或一些完全不同的过滤器)的函数W == 1
,W == 0
NSE 会使这更难完成。
2017 年,tidyverse 开始在tidy 评估中构建解决方案。