按分组保留最频繁字符值并汇总数值列的实现方法
分组汇总方案:数值求和+提取众数字符值
以下是针对需求的几种实现方式,优先使用dplyr,同时提供备选方案:
方法一:dplyr + 自定义众数函数
通过自定义函数提取每组字符列的众数,结合分组求和完成汇总:
library(dplyr) # 自定义众数函数:返回组内出现次数最多的字符(多众数时取第一个) get_mode <- function(x) { freq_table <- table(x) names(freq_table)[which.max(freq_table)] } # 原始数据 have <- data.frame( id = c(1,1,1,2,2,2), a = c("dog","dog","cat","duck","duck","horse"), value = c(1,2,3,4,5,6) ) # 分组汇总 need <- have %>% group_by(id) %>% summarise( a = get_mode(a), value = sum(value), .groups = "drop" # 取消分组状态 ) # 输出结果 need
方法二:纯dplyr内置函数实现
无需自定义函数,通过count和slice_max组合完成众数提取:
library(dplyr) need <- have %>% group_by(id) %>% mutate(total_value = sum(value)) %>% # 先计算每组数值总和 count(a, total_value, .drop = FALSE) %>% # 统计每组内各字符的出现次数 slice_max(n, n = 1) %>% # 筛选出现次数最多的行 select(id, a, value = total_value) %>% # 整理目标列 ungroup()
方法三:data.table备选方案
如果习惯使用data.table,可采用更高效的分组操作:
library(data.table) setDT(have) need <- have[, .( a = names(which.max(table(a))), value = sum(value) ), by = id]
注意事项
如果某组字符列存在多个众数(即多个值出现次数相同且为最高),上述方法默认返回第一个出现的众数。若需保留所有众数,可修改众数提取逻辑,例如返回以逗号分隔的字符串,或保留多行记录。
内容的提问来源于stack exchange,提问作者Léon Ipdjian
相关产品推荐
相关产品推荐

