dplyr分组聚合时如何获取最大值对应的STATUS列值
问题与解决方案
测试数据
首先构造测试数据框:
YEAR <- c(2019, 2019,2020, 2020, 2019,2020,2020,2019,2020) GROUP <- c("A","A","A", "A","B","B","B","A","B") VALUE <- c(1,4,3, 8 ,5,3,2,6,7) STATUS <- c("on","off", "off", "on", "on", "on", "off", "off", "off") testdata <- data.frame(YEAR, GROUP, STATUS, VALUE)
问题描述
按YEAR和GROUP分组后,需要同时获取每组VALUE的最大值,以及该最大值对应的STATUS值。直接用summarise结合first(STATUS)无法得到正确结果——first(STATUS)取的是分组内第一条记录的状态,而非最大值对应的状态。比如2019年GROUP A的最大值是6,对应的STATUS应为off,但错误代码返回的是on。
解决方案
方法1:用slice_max筛选最大值所在行
直接筛选出每组中VALUE最大的行,保留所有需要的列:
library(dplyr) testdata %>% group_by(YEAR, GROUP) %>% slice_max(n = 1, order_by = VALUE) %>% rename(max_value = VALUE) %>% ungroup()
如果每组存在多个相同最大值的记录,n = 1只会取第一条;若要保留所有最大值记录,可去掉n = 1参数。
方法2:在summarise中匹配最大值对应的STATUS
先计算最大值,再通过匹配逻辑获取对应的STATUS:
testdata %>% group_by(YEAR, GROUP) %>% summarise( max_value = max(VALUE), STATUS = STATUS[VALUE == max_value] ) %>% ungroup()
如果同一组有多个相同最大值,STATUS会返回一个向量;若要确保只返回一个值,可结合first()或unique(),比如STATUS = first(STATUS[VALUE == max_value])。
方法3:用filter结合group_by
先分组计算最大值,再筛选出等于最大值的行:
testdata %>% group_by(YEAR, GROUP) %>% filter(VALUE == max(VALUE)) %>% rename(max_value = VALUE) %>% ungroup()
这种方法和slice_max效果类似,同样会保留所有最大值对应的记录。
内容的提问来源于stack exchange,提问作者EllisR8
相关产品推荐
相关产品推荐

