Фильтрация с использованием dplyr с именами столбцов и условиями в качестве строк - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь написать простую функцию для фильтрации 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? Длина обеих строк в действительности намного длиннее.

Ответы [ 2 ]

3 голосов
/ 07 октября 2019

Альтернативный способ думать об этом состоит в том, что у вас есть набор данных условий, которые вы хотите использовать для фильтрации ваших основных данных. Создайте небольшой фрейм данных условий и соответствующих им имен переменных, а затем преобразуйте его в фрейм данных, где эти имена переменных являются именами столбцов. Затем используйте 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
2 голосов
/ 07 октября 2019

1) sym - Мы можем конвертировать в sym bols и eval uate (!!). [[ используется в основном для извлечения list элементов. Поскольку OP показывал оба 'vars' и 'cond' как vector s [ достаточно для извлечения каждого элемента

nycflights13::planes %>%
   filter(
    !!rlang::sym(vars[1]) == cond[1],
     !!rlang::sym(vars[2]) == cond[2]
  )

2) parse_expr- Опцияэто создать выражение с paste или str_c из stringr, а затем проанализировать это выражение

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

3) map2 / reduce - Если у нас большеодин столбец, тогда мы могли бы использовать filter_at, но здесь «cond» разные. Итак, один из вариантов map2

library(purrr)
library(dplyr)
map2(vars, cond, ~ nycflights13::planes %>%
                       transmute(ind = !! rlang::sym(.x) == .y) %>%
                       pull(ind)) %>%
     reduce(`&`) %>%
     filter(nycflights13::planes, .)
# 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...