我有一个与数据框中的列同名的变量:
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
是指外部变量。
答案 0 :(得分:16)
您可以使用get
函数从环境中获取变量的值。
df %>% filter(b == get("b")) # Note the "" around b
答案 1 :(得分:16)
最近我发现这是解决这个问题的一个优雅的解决方案,尽管我只是开始关注它是如何工作的。
df %>% filter(b == UQ(b))
是
的语法糖 UQ
我对此的高级认识是!!
(取消引用)操作会导致在筛选操作之前评估其内容,因此不会在data.frame中对其进行评估。
在{quasi-quotation'下的answer中对此进行了描述。我要注意的是,本文还包括一些与NSE相关的类似问题的解决方案。
对上述内容的一个警告 - 我倾向于将df %>% filter(!!b == b)
置于我的表达式的末尾,如上所述。如果你把它放在开头:
df %>% filter(!!(b == b))
然后它将被评估为df %>% filter(5 == 5)
相当于写> quo(filter(df, !!b == b))
<quosure: global>
~filter(df, TRUE)
:
UQ()
上面的 if (as.numeric(fld 3) > 100)
{
x <- data.frame(computed fld1, computed fld 2, computed fld3)
write.table(x, "outputfile.csv", sep=",",append=TRUE, quote=FALSE,
col.names=FALSE, row.names=FALSE)
}
选项没有此问题。
答案 2 :(得分:8)
作为一般解决方案,您可以使用filter
的SE(标准评估)版本,即filter_
。在这种情况下,事情变得有点混乱,因为你正在混合一个变量和一个外部&#39;单个表达式中的常量。以下是使用interp
函数执行此操作的方法:
library(lazyeval)
df %>% filter_(interp(~ b == x, x = b))
如果您想在b
中使用更多值,可以写:
df %>% filter_(interp(~ b == x, .values = list(x = b)))