如何按多条件分组DataFrame,统计大于组均值的数值数量?
高效实现分组计算均值并统计大于均值的次数
需求:在大型DataFrame中完成以下操作:
- 按
stage和sex多条件分组 - 计算每组中各变量(如
cort、granu)的均值 - 统计每组内大于对应组均值的数值出现次数
当前实现方式存在冗余:先用aggregate计算组均值,再通过dplyr手动筛选每个分组、判断数值是否大于均值并统计,需要重复编写大量代码,效率低下。
示例DataFrame:
stage sex cort granu a m 0.53 50 a m 0.65 93 a f 3.18 49 a m 1.51 45 a m 0.28 57 a f 0.50 36 a f 1.20 21 a f 2.36 58 b m 0.27 74 b m 0.16 36 b f 0.42 27 b m 0.88 65 b f 2.19 85 b m 0.24 74 b f 0.89 52 b m 0.34 98 b f 2.59 52 b f 0.74 63 c m 6.36 54 c f 2.07 24 c m 1.46 12 c m 2.07 36 c f 1.46 75 c m 2.19 96 c f 6.36 21 c f 2.19 85
当前冗余代码片段:
mean_c<- aggregate(x= data$cort, by = list(data$sex,data$stage), FUN = mean) cah<-dplyr::filter(data,stage=="a" & sex=="h") cah<-dplyr::select(cah, c(cort)) countah<-corta>1.81 #mean for the group (a,h) cam<-dplyr::filter(data,stage=="a" & sex=="m") cam<-dplyr::select(cam, c(cort)) countam<-corta>0.74 #mean for the group (a,m) sum(countah)
方法1:使用dplyr链式操作(推荐,代码简洁易读)
利用dplyr的分组后计算均值,再直接在分组内统计大于均值的次数,无需手动拆分每个分组:
library(dplyr) result <- data %>% group_by(stage, sex) %>% mutate( # 计算每组各变量的均值 cort_mean = mean(cort, na.rm = TRUE), granu_mean = mean(granu, na.rm = TRUE), # 判断当前值是否大于组均值 cort_above_mean = cort > cort_mean, granu_above_mean = granu > granu_mean ) %>% # 分组统计大于均值的次数 summarise( cort_count_above = sum(cort_above_mean, na.rm = TRUE), granu_count_above = sum(granu_above_mean, na.rm = TRUE), # 保留组均值方便查看 cort_mean = first(cort_mean), granu_mean = first(granu_mean) ) %>% ungroup() print(result)
说明:
group_by(stage, sex):按指定字段分组mutate:在原数据中新增列,计算组均值和判断逻辑summarise:分组汇总统计次数,同时保留组均值na.rm = TRUE:处理可能存在的缺失值,避免计算出错
方法2:使用data.table(适合超大型数据集,速度更快)
如果你的DataFrame数据量极大,data.table的运算效率会优于dplyr:
library(data.table) setDT(data) # 将普通DataFrame转为data.table格式 result <- data[, .( cort_mean = mean(cort, na.rm = TRUE), granu_mean = mean(granu, na.rm = TRUE), cort_count_above = sum(cort > mean(cort, na.rm = TRUE), na.rm = TRUE), granu_count_above = sum(granu > mean(granu, na.rm = TRUE), na.rm = TRUE) ), by = .(stage, sex) ] print(result)
说明:
by = .(stage, sex):指定分组字段- 直接在分组计算中同时完成均值计算和次数统计,无需中间变量
data.table的语法更紧凑,内存占用更低,适合处理百万级以上数据
这两种方法都能一次性完成所有分组的计算,无需手动重复编写每个分组的筛选和判断代码,大幅提升效率和代码可维护性。
内容的提问来源于stack exchange,提问作者user228095
相关产品推荐
相关产品推荐

