使用 dplyr 进行 eval 解析的替代方法

hxa*_*emy 2 eval r dplyr tidyverse

有没有办法在不使用 eval(parse()) 的情况下使用字符串作为参数进行过滤?

library("dplyr")

subset <- "carb == 4"
subset_df <- mtcars %>% filter(eval(parse(text = subset)))
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 5

1) rlang如果你要问的是在 tidyverse 中是否有对应的 eval/parse,那么,是的,有。您还需要 dplyr 已经使用的 rlang,但 dplyr 不导出所需的函数,因此使用库语句加载它。

library(dplyr)
library(rlang)

subset <- "carb == 4"
mtcars %>% filter(eval_tidy(parse_expr(subset)))
Run Code Online (Sandbox Code Playgroud)

给予:

                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
Run Code Online (Sandbox Code Playgroud)

1a)这也有效:

mtcars %>% filter(!!parse_quo(subset, .GlobalEnv))
Run Code Online (Sandbox Code Playgroud)

2) sqldf如果您正在寻找一种不使用 eval/parse 或任何直接替代方法的方法来执行此操作,并且不需要使用 tidyverse,那么 sqldf 可以执行该操作,前提是提供subset包含有效 SQL 的情况下的问题做。

library(sqldf)
subset <- "carb == 4"
fn$sqldf("select * from mtcars where $subset")
Run Code Online (Sandbox Code Playgroud)

给予:

    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  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
4  19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
5  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
6  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
7  10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
8  14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
9  13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
10 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
Run Code Online (Sandbox Code Playgroud)

2a)这也可以写成这样的管道:

mtcars %>% { fn$sqldf("select * from '.' where $subset") }
Run Code Online (Sandbox Code Playgroud)