Фильтрация по области действия в диапазоне столбцов с помощью & logic - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь найти метод фильтрации по определенному диапазону столбцов во фрейме данных, чтобы отфильтровать строки, содержащие все элементы символьного вектора где-то в этом диапазоне столбцов.

Например, если мой диапазон столбцов был ниже:

library(dplyr)

set.seed(10)

df <- tibble(
  a = sample(LETTERS[1:10], 10),
  b = sample(LETTERS[1:10], 10),
  c = sample(LETTERS[1:10], 10),
  d = sample(LETTERS[1:10], 10),
  e = sample(LETTERS[1:10], 10)
)

df
#> # A tibble: 10 x 5
#>    a     b     c     d     e    
#>    <chr> <chr> <chr> <chr> <chr>
#>  1 F     G     I     F     C    
#>  2 C     F     F     A     J    
#>  3 D     A     G     B     A    
#>  4 E     E     C     G     F    
#>  5 A     C     H     C     B    
#>  6 B     I     D     D     H    
#>  7 G     H     E     E     E    
#>  8 J     D     A     J     G    
#>  9 H     J     B     H     D    
#> 10 I     B     J     I     I

, и я хотел отфильтровать строки, которые имели хотя бы один экземпляр "A" и хотя бы один экземпляр "C" Я мог бы использовать filter_at дважды, чтобы получить желаемый результат:

df %>% 
  filter_at(vars(a:e), any_vars(. == "A")) %>% 
  filter_at(vars(a:e), any_vars(. == "C"))
#> # A tibble: 2 x 5
#>   a     b     c     d     e    
#>   <chr> <chr> <chr> <chr> <chr>
#> 1 C     F     F     A     J    
#> 2 A     C     H     C     B

Тем не менее, я пытаюсь реализовать это в блестящем, где критерии фильтра приходят как вектор c("A", "C") из выбранного входа, так чтоесть ли способ сделать это с помощью единственной функции фильтра, использующей вектор?

Использование %in% не сработает, поскольку возвращает любые строки с "A" или "C"

df %>% 
  filter_at(vars(a:e), any_vars(. %in% c("A", "C")))
#> # A tibble: 6 x 5
#>   a     b     c     d     e    
#>   <chr> <chr> <chr> <chr> <chr>
#> 1 F     G     I     F     C    
#> 2 C     F     F     A     J    
#> 3 D     A     G     B     A    
#> 4 E     E     C     G     F    
#> 5 A     C     H     C     B    
#> 6 J     D     A     J     G

Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Полностью tidyverse решение, хотя вызовы as_data_frame и $ кажутся некрасивыми, а вложенные функции не идеальны, все они обрабатываются в конвейере без цикла.

target = c('A', 'C')

flag = df %>% 
  select(a:e) %>%  # If you have other columns, this does the same scoping
  rowwise %>% 
  do(as_data_frame(all(target %in% .))) %>% 
  .$value

df %>% filter(flag)
#> # A tibble: 2 x 5
#>   a     b     c     d     e    
#>   <chr> <chr> <chr> <chr> <chr>
#> 1 C     F     F     A     J    
#> 2 A     C     H     C     B

Создано в 2019-02-01 пакетом Представить (v0.2.1)

У меня есть давние воспоминания о rowwise вызовы довольно медленные дляочень длинные data.frames, но это будет специфично для вашего приложения.

0 голосов
/ 01 февраля 2019

Вы можете фильтровать в цикле:

filter_vec <- c("A", "C")

df_filtered <- df
for (f in filter_vec) {
  df_filtered <- filter_at(df_filtered,
                           vars(a:e),
                           any_vars(. == f))
}

df_filtered
#> # A tibble: 2 x 5
#>   a     b     c     d     e    
#>   <chr> <chr> <chr> <chr> <chr>
#> 1 C     F     F     A     J    
#> 2 A     C     H     C     B    
...