我有一个与数据框中的列同名的变量:
df <- data.frame(a=c(1,2,3), b=c(4,5,6))
b <- 5
我想得到 df$b == b
的行,但是dplyr将其解释为 df$b == df$b
:
df %>% filter(b == b) # interpreted as df$b == df$b
# a b
# 1 1 4
# 2 2 5
# 3 3 6
如果我更改变量名称,它可以工作:
B <- 5
df %>% filter(b == B) # interpreted as df$b == B
# a b
# 1 2 5
我想知道是否有更好的方法告诉 filter
b
指的是外部变量 .
3 回答
您可以使用
get
函数从环境中获取变量的值 .最近我发现这是解决这个问题的一个优雅的解决方案,尽管我只是开始关注它是如何工作的 .
df %>% filter(b == !!b)
这是语法糖
df %>% filter(b == UQ(b))
我的高级意义是
UQ
(取消引用)操作导致其内容在过滤操作之前被评估,因此它不在data.frame中进行评估 .这在article中描述,在'quasi-quotation'下 . 我要注意的是,本文还包括一些与NSE相关的类似问题的解决方案 .
对上面的一个警告 - 我倾向于将
!!
置于我的表达式的末尾,如上所述 . 如果你把它放在开头:df %>% filter(!!b == b)
那么它将被评估为
df %>% filter(!!(b == b))
这相当于写
df %>% filter(5 == 5)
:上面的
UQ()
选项没有这个问题 .作为一般解决方案,您可以使用
filter
的SE(标准评估)版本,即filter_
. 在这种情况下,事情变得有点混乱,因为您在一个表达式中混合变量和'external'常量 . 以下是使用interp
函数执行此操作的方法:如果您想在
b
中使用更多值,您可以写: