R语言按个体分组计算排除NA值的累积均值方法
R按分组计算排除NA的累积均值实现方案
前置问题修正
你提供的原始数据集构造代码存在一个隐性问题:代码里的"na"是字符串类型,R无法将其识别为缺失值,且Temp_Diff和Day字段默认会被读成字符型,直接计算会报错,需要先做类型转换:
library(dplyr) library(tidyr) # 构造规范数据集 df <- data.frame( Cow_ID = c("192","192","192","192","201","201","201","201","652","652","652","652"), Day = as.numeric(c("1","2","3","4","1","2","3","4","1","2","3","4")), Temp_Diff = as.numeric(c("0.2","0.1","na","0.8","0.4","0.1","0.7","na","0.1","0.3","na","0.8")) )
核心问题原因
你写的原代码没有加分组逻辑,cummean()会默认对整个数据集的所有非缺失值计算累积均值,自然不会在切换Cow_ID的时候重置计算起点。
正确实现代码
只需要在mutate()前增加group_by(Cow_ID)步骤,就能让所有计算按每个牛的ID独立执行,切换个体时自动重置累积计算的状态:
df <- df %>% group_by(Cow_ID) %>% # 按个体ID分组,组内独立计算 mutate( cum_avg_temp = replace(Temp_Diff, !is.na(Temp_Diff), cummean(Temp_Diff[!is.na(Temp_Diff)])) ) %>% fill(cum_avg_temp, .direction = "down") %>% # 用前序非NA的累积均值填充缺失值行 ungroup() # 计算完成后取消分组,避免干扰后续操作
计算结果说明
以ID为192的牛为例,计算结果如下:
- Day1(Temp_Diff=0.2):累积均值为0.2
- Day2(Temp_Diff=0.1):累积均值为(0.2+0.1)/2 = 0.15
- Day3(Temp_Diff=NA):沿用上一行的累积均值0.15
- Day4(Temp_Diff=0.8):累积均值为(0.2+0.1+0.8)/3 ≈ 0.367
后续ID为201、652的牛会从各自的第一条记录开始重新计算累积均值,不会混入其他个体的数值。
注意事项
- 所有数值计算前必须确保缺失值是R原生识别的
NA类型,不要用字符串"na"存储缺失值,否则所有统计函数都会无法正常运行。 - 分组计算完成后建议执行
ungroup()取消分组状态,否则后续对数据集做筛选、汇总等操作时会默认沿用分组规则,出现不符合预期的结果。
内容的提问来源于stack exchange,提问作者Jennifer Weller
相关产品推荐
相关产品推荐

