【问题标题】:Avoid conflicts between vector and variable name in dplyr避免 dplyr 中向量和变量名之间的冲突
【发布时间】:2014-11-10 14:37:56
【问题描述】:

我在一个将 data.frame df 作为参数的函数中使用了dplyr

有时,我想根据我刚刚创建的名为n 的向量进行过滤。但是,如果 n 也是输入 data.frame 中变量的名称,这将不起作用。

library(dplyr)
df <- data.frame(n = c(0L, 0L))
n <- c(1L, 1L)
filter(df, n == 1L)
#> [1] n
#> <0 rows> (or 0-length row.names)

由于该函数适用于任何数据帧,我想避免这种情况。我尝试使用与全局环境关联的公式/惰性对象,但这返回了相同的结果:

a <- ~ n == 1L
filter_(df, a)
#> [1] n
#> <0 rows> (or 0-length row.names)
a <- lazy(n == 1L)
filter_(df, a)
#> [1] n
#> <0 rows> (or 0-length row.names)

有没有优雅的方法来做到这一点?

【问题讨论】:

  • 一个选项是filter(df, get('n', envir = .GlobalEnv) == 1L)
  • 谢谢。您知道使用filter_lazy_eval 中的某些功能的解决方案吗?这就是我尝试使用公式的方法 - 我认为该公式将在全球环境中进行评估。

标签: r lazy-evaluation dplyr


【解决方案1】:

所有以前的答案都已过时,因为 dplyr 现在支持 rlang 引用和取消引用语义。

您可以简单地使用!! n 来防止n 被引用(并解释为n 列)。

library(dplyr)
df <- data.frame(n = c(0L, 0L))
n <- c(1L, 1L)
filter(df, !! n == 1L)

##   n
## 1 0
## 2 0

另一个使用经典mtcars的例子:

gear <- 5

# gear == gear is true for all rows!
# this returns the whole dataset
filter(mtcars, gear == gear)

# this works as intended
filter(mtcars, gear == !! gear)

##   mpg cyl  disp  hp drat    wt qsec vs am gear carb
## 1 26.0   4 120.3  91 4.43 2.140 16.7  0  1    5    2
## 2 30.4   4  95.1 113 3.77 1.513 16.9  1  1    5    2
## 3 15.8   8 351.0 264 4.22 3.170 14.5  0  1    5    4
## 4 19.7   6 145.0 175 3.62 2.770 15.5  0  1    5    6
## 5 15.0   8 301.0 335 3.54 3.570 14.6  0  1    5    8

【讨论】:

    【解决方案2】:

    因为n 既是变量名又是包含值的对象,使用 lazyeval 中的 interp 并使用 n 作为值(而不是变量)似乎做了什么你想要的。

    library(lazyeval)
    filter_(df, interp(~n == 1L, n = n))
    
      n
    1 0
    2 0
    

    我首先尝试了更复杂的

    filter_(df, interp(~n == 1L, .values = list(n = n)))
    

    但更简单的版本似乎工作方式相同。

    【讨论】:

    • 是的,我也认为我必须传递价值。谢谢!
    【解决方案3】:

    正如您所说,可能有一种方法可以使用 NSE 和filter_ 来做到这一点,但不确定如何。我希望像df %&gt;% filter_(n == 1L) 这样的东西可以工作——它确实使用了正确的n,但它只使用了向量的第一个条目。这个替代方案怎么样

    df %>% `[`(n == 1L, ,drop = F)
    #  n
    #1 0
    #2 0
    

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 2020-03-22
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2014-10-09
      • 1970-01-01
      相关资源
      最近更新 更多