首页 > 解决方案 > 总结到最大的类别

问题描述

我有时会遇到一个问题。我想折叠我的数据框,并且一列应该返回组中最大的类别,即使每个类别有多个观察值。例子:

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,因为 D 的 val 总和大于 cat 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解决方案或什么的?

谢谢!:)

标签: rdplyrtidyverseforcats

解决方案


我们可以计算并选择每个group_by cat中值为 的行。grpsummaxsumgrp

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          

推荐阅读