Комплексная фильтрация dplyr group_by - PullRequest
1 голос
/ 27 января 2020

Я не могу понять, как написать сложные критерии фильтрации для групп в Tidyverse. Рассмотрим пример кадра данных ниже:

df <- tibble(
    a = c(1,1,1,2,2,2,2,3), 
    b = c(1,2,3,1,4,50,5,3),
    c = c("PIZZA", "HAM", NA, "COKE", "LOBSTER", "LOBSTER", NA, NA),
)

Я хочу, чтобы a была моей переменной группировки, а затем выберите запись с самой большой записью в b, чтобы запись в c не была NA. Желаемый результат:

tibble(
    a = c(1, 2, 3),
    b = c(2, 50, 3),
    c = c("HAM", "LOBSTER", NA)
)

Конечно, я могу сделать

df %>% group_by(a) %>% filter(b == max(b))

, но тогда я не удовлетворяю критерию столбца c. Некоторые сложности:

  1. Число записей между группами не согласовано.
  2. Если запись c равна NA для всех записей в группе, выберите наибольшее значение b запись с NA.

Ответы [ 3 ]

2 голосов
/ 27 января 2020

На основе обновленного примера вы можете пометить группы, где c - это только NA для использования в качестве второго условия фильтрации. Я делаю это более многословным, чем нужно для иллюстрации - вам, вероятно, не нужно сохранять all_na в качестве переменной, например, просто сделайте это вычисление встроенным в первом вызове filter. В этом случае измените мое первоначальное предложение фильтрации для !is.na(c), чтобы оно соответствовало этим или случаям, когда все значения c равны NA.

library(dplyr)

df %>%
  group_by(a) %>%
  mutate(all_na = all(is.na(c))) %>%
  filter(!is.na(c) | all_na) %>%
  filter(b == max(b))
#> # A tibble: 3 x 4
#> # Groups:   a [3]
#>       a     b c       all_na
#>   <dbl> <dbl> <chr>   <lgl> 
#> 1     1     2 HAM     FALSE 
#> 2     2    50 LOBSTER FALSE 
#> 3     3     3 <NA>    TRUE
1 голос
/ 27 января 2020

Как насчет этого:

library(tidyverse)

df %>%
  group_by(a) %>%
  filter(b == max(b),
         !is.na(c))
1 голос
/ 27 января 2020

Мы можем подмножество 'b', где нет элементов NA в 'c' после группировки по 'a'

library(dplyr)
df %>% 
    group_by(a) %>% 
     slice(if(all(is.na(c))) 1 else which.max(b[!is.na(c)]))
# A tibble: 3 x 3
# Groups:   a [3]
#      a     b c      
#  <dbl> <dbl> <chr>  
#1     1     2 HAM    
#2     2    50 LOBSTER
#3     3     3 <NA>   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...