我尝试编写一个简单的函数来过滤data.frame。列名和过滤条件都存储为字符串:
vars <- c("manufacturer", "engine")
cond <- c("EMBRAER", "Turbo-fan")
输出应与通过以下方式获得的输出相同:
library(dplyr)
library(nycflights13)
nycflights13::planes %>%
filter(
.data[[vars[[1]]]] == cond[[1]],
.data[[vars[[2]]]] == cond[[2]]
)
使用dplyr + purrr进行此操作的方式是什么?实际上,两个字符串的长度都更长。
答案 0 :(得分:3)
对此进行考虑的另一种方法是,您具有要用于过滤主数据的条件数据集。创建一个包含条件及其相应变量名的小型数据框,然后将其重塑为一个数据框,其中这些变量名是列名。然后使用semi_join
将只有变量和条件组合匹配的数据行保留在条件数据框中。
vars <- c("manufacturer", "engine")
cond <- c("EMBRAER", "Turbo-fan")
library(dplyr)
library(nycflights13)
cond_df <- data.frame(vars, cond) %>%
tidyr::spread(key = vars, value = cond)
nycflights13::planes %>%
semi_join(cond_df, by = vars)
#> # A tibble: 298 x 9
#> tailnum year type manufacturer model engines seats speed engine
#> <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
#> 1 N10156 2004 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 2 N10575 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 3 N11106 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 4 N11107 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 5 N11109 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 6 N11113 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 7 N11119 2002 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 8 N11121 2003 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 9 N11127 2003 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> 10 N11137 2003 Fixed wing… EMBRAER EMB-1… 2 55 NA Turbo…
#> # … with 288 more rows
答案 1 :(得分:2)
1)sym -我们可以转换为sym
大括号和eval
uate(!!
)。 [[
主要用于提取list
元素。正如OP显示vector
的{{1}}一样,'vars'和'cond'足以提取每个元素
[
2)parse_expr-:一种选择是使用nycflights13::planes %>%
filter(
!!rlang::sym(vars[1]) == cond[1],
!!rlang::sym(vars[2]) == cond[2]
)
中的paste
或str_c
创建一个表达式,然后解析该表达式
stringr
3)map2 / reduce-如果我们有多于一列,则可以使用expr1 <- str_c(vars, str_c('"', cond, '"'), sep="==", collapse=" & ")
nycflights13::planes %>%
filter(!! rlang::parse_expr(expr1))
# A tibble: 298 x 9
# tailnum year type manufacturer model engines seats speed engine
# <chr> <int> <chr> <chr> <chr> <int> <int> <int> <chr>
# 1 N10156 2004 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 2 N10575 2002 Fixed wing multi engine EMBRAER EMB-145LR 2 55 NA Turbo-fan
# 3 N11106 2002 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 4 N11107 2002 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 5 N11109 2002 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 6 N11113 2002 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 7 N11119 2002 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 8 N11121 2003 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# 9 N11127 2003 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
#10 N11137 2003 Fixed wing multi engine EMBRAER EMB-145XR 2 55 NA Turbo-fan
# … with 288 more rows
,但是这里的“条件”是不同的。因此,一种选择是filter_at
map2