Подведите итог к самой большой категории - PullRequest
0 голосов
/ 23 апреля 2020

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

library(dplyr)
df <- tibble(grp = c(1, 1, 1, 1, 2, 2, 2, 2),
             cat = c("A", "B", "B", "A", "C", "D", "C", "C"),
             val = c(1, 2, 1, 4, 1, 8, 2, 1))

# # A tibble: 8 x 3
# grp cat     val
# <dbl> <chr> <dbl>
# 1     1 A         1
# 2     1 B         2
# 3     1 B         1
# 4     1 A         4
# 5     2 C         1
# 6     2 D         8
# 7     2 C         2
# 8     2 C         1

Ожидаемый результат:

# A tibble: 2 x 3
    grp val biggest_cat
  <dbl>    <dbl> <chr>      
1     1        8 A          
2     2       12 D   

Обратите внимание, что для группы 2 я хочу вернуть cat D, так как сумма val для D больше чем сумма для кошки C.

Это работает:

df %>% 
  group_by(grp, cat) %>% 
  summarise(val = sum(val)) %>% 
  group_by(grp) %>% 
  summarise(val = sum(val),
           biggest_cat = first(cat, order_by = -val))

Но я хочу сделать это без двойного суммирования:

df %>% 
  group_by(grp) %>% 
  summarise(val = sum(val),
           biggest_cat = <Some function>)

Может быть, есть решение forcats или что-то?

Спасибо! :)

1 Ответ

1 голос
/ 23 апреля 2020

Мы могли бы group_by cat, grp вычислить sum и выбрать строку с max значением sum в каждом grp.

library(dplyr)
df %>% 
  group_by(grp, cat) %>% 
  summarise(val = sum(val)) %>%
  summarise(cat = cat[which.max(val)],
            biggest_cat = sum(val))

Чтобы сделать это с помощью одного summarise, мы можем использовать tapply:

df %>% 
  group_by(grp) %>% 
  summarise(total_val = sum(val), 
            biggest_cat = names(which.max(tapply(val, cat, sum))))


#    grp total_val biggest_cat
#  <dbl>     <dbl> <chr>      
#1     1         8 A          
#2     2        12 D          
...