如何在R中基于anemia_start列重置向后移动平均值?
基于贫血起始标记重置的向后累积平均值计算(R语言实现)
问题需求
针对包含患者血红蛋白水平的数据集,需计算向后(非居中)累积平均值:
- 按患者ID(
pt_id)独立计算 - 当
anemia_start列值为1时(标记患者首次血红蛋白低于7的时刻),重置累积平均值的计算起点
示例数据
df <- data.frame(pt_id = c(1,1,1,1,1), hemoglobin_level = c(8,6,5,8,7), anemia_start = c(0,1,0,0,0)) # 打印原始数据 df #> pt_id hemoglobin_level anemia_start #> 1 1 8 0 #> 2 1 6 1 #> 3 1 5 0 #> 4 1 8 0 #> 5 1 7 0
期望输出
新增moving_average列,结果为:
moving_average = c(8, 6, 5.5, 6.3, 6.5)
解决方案
使用dplyr包实现分组重置后的累积平均计算,步骤清晰且高效:
library(dplyr) df_processed <- df %>% # 按患者ID分组,确保每个患者的计算独立 group_by(pt_id) %>% # 生成重置分组标记:每次anemia_start=1时,分组号递增 mutate(reset_group = cumsum(anemia_start)) %>% # 按患者ID+重置分组标记,计算子组内的累积平均 group_by(pt_id, reset_group) %>% mutate(moving_average = cummean(hemoglobin_level)) %>% # 取消分组,清理临时列 ungroup() %>% select(-reset_group) # 查看处理后的数据 df_processed #> pt_id hemoglobin_level anemia_start moving_average #> 1 1 8 0 8.000000 #> 2 1 6 1 6.000000 #> 3 1 5 0 5.500000 #> 4 1 8 0 6.333333 #> 5 1 7 0 6.500000
代码说明
- 患者分组:通过
group_by(pt_id)确保每个患者的计算互不干扰 - 重置标记生成:
cumsum(anemia_start)会生成递增的分组ID,每当遇到anemia_start=1时,后续行被划入新的子组,实现重置效果 - 累积平均计算:
cummean()函数会计算从子组起始行到当前行的均值,正好匹配需求中"重置后持续计算向后移动平均"的逻辑 - 结果清理:取消分组并移除临时的
reset_group列,得到整洁的输出数据
内容的提问来源于stack exchange,提问作者Henrik Ode
相关产品推荐
相关产品推荐

