使用变量中的值作为参数的Filter()

Jer*_* K. 0 r dplyr tidyverse

我希望能够filter(),其中参数值是已经定义的变量。

因此,例如,使用可重现的mtcars数据集:

library(tidyverse)
df <- mtcars
head(df)
#>                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
Run Code Online (Sandbox Code Playgroud)

我想使用:

filter_by <-  "cyl"
filter_equal <- 6
Run Code Online (Sandbox Code Playgroud)

我尝试了以下操作,但输出的行数为零。

df %>% filter(filter_by == filter_equal)
#>  [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
#> <0 rows> (or 0-length row.names)
Run Code Online (Sandbox Code Playgroud)

我想要的输出是这样的(但使用变量filter_byfilter_equal):

df %>% filter(cyl == 6)
#>    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> 3 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> 4 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> 5 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> 6 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> 7 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
Run Code Online (Sandbox Code Playgroud)

reprex软件包(v0.2.1)创建于2019-08-25

Ron*_*hah 5

如果要使用非标准评估(NSE),则需要转换filter_by为符号(sym),然后评估(!!

library(dplyr)
library(rlang)

df %>% filter(!!sym(filter_by) == filter_equal)

#   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#3 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#4 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#5 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#6 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#7 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
Run Code Online (Sandbox Code Playgroud)

我们也可以使用 get

df %>% filter(get(filter_by) == filter_equal)
Run Code Online (Sandbox Code Playgroud)

在基础R中没有NSE,我们可以直接

df[df[[filter_by]] == filter_equal, ]
Run Code Online (Sandbox Code Playgroud)