如何按分组计算日期的滚动7天累计剂量?
滚动计算分组内7天累计剂量问题
需求说明
- 创建
total_dose变量,持续累加dosage的值 - 当某条
dosage记录距离当前记录超过7天时,从total_dose中减去该值,滚动执行 - 当
pid(患者ID)或medname(药物名称)变更时,total_dose需重新开始计数
示例数据集
pid medname date route dosage 1 1 drugA 2023-04-15 17:30:00 patch 30 2 1 drugA 2023-04-16 11:45:00 patch 30 3 1 drugA 2023-04-17 10:30:00 patch 30 4 2 drugB 2023-04-27 22:00:00 patch 30 5 2 drugB 2023-04-30 13:15:00 patch 30 6 2 drugB 2023-05-10 13:15:00 patch 30 7 2 drugA 2023-05-11 06:30:00 patch 30
期望输出
pid medname date route dosage total_dose 1 1 drugA 2023-04-15 17:30:00 patch 30 30 2 1 drugA 2023-04-16 11:45:00 patch 30 60 3 1 drugA 2023-04-17 10:30:00 patch 30 90 4 2 drugB 2023-04-27 22:00:00 patch 30 30 5 2 drugB 2023-04-30 13:15:00 patch 30 60 6 2 drugB 2023-05-10 13:15:00 patch 30 30 7 2 drugA 2023-05-11 06:30:00 patch 30 30
已尝试的代码
方法一:使用transform与ave
df2 <- transform(df1, total_dosage = ave(dosage, list(pid, medname, cumsum(c(0, diff(as.numeric(date - date[1]))) > 604800)), FUN = cumsum))
方法二:结合group_by与transform
df2 <- df1 %>% group_by(pid, medname) %>% arrange(date, .by_group = TRUE) df3 <- transform(df2, total_dose = ave(dose, cumsum(c(0, diff(as.numeric(date - date[1]))) > 604800), FUN=cumsum))
方法三:扩展分组逻辑
df2 <- df1 %>% group_by(pid, medname) %>% arrange(date, .by_group = TRUE) df3 <- transform(df2, time_since_first_dose = cumsum(c(0, diff(as.numeric(date - date[1])))), group_change = cumsum(c(TRUE, diff(pid) != 0 | diff(medname) != 0)), total_dose = ave(dosage, group_change, time_since_first_dose, FUN=cumsum))
正确解决方案
之前的尝试仅按固定时间切割分组累加,未实现滚动移除超过7天记录的核心逻辑。以下用dplyr结合slider包实现需求:
代码实现
# 安装并加载依赖包 if (!require("dplyr")) install.packages("dplyr") if (!require("slider")) install.packages("slider") library(dplyr) library(slider) # 数据处理 df_result <- df1 %>% # 转换日期为时间格式(若未转换) mutate(date = as.POSIXct(date)) %>% # 按患者、药物分组,组内按日期排序 group_by(pid, medname) %>% arrange(date, .by_group = TRUE) %>% # 计算滚动7天内的剂量总和 mutate(total_dose = slide_dbl( .x = dosage, .i = date, .f = sum, .before = days(7), .complete = FALSE )) %>% ungroup()
代码说明
slide_dbl是slider包的滑动窗口函数,专门处理时序滚动计算.i = date指定以日期为窗口索引,确保窗口范围基于实际时间.before = days(7)定义窗口为当前日期往前推7天的范围.complete = FALSE表示即使窗口未填满7天,也计算现有记录的总和,符合持续累加的需求
运行后即可得到期望输出。
内容的提问来源于stack exchange,提问作者db2020
相关产品推荐
相关产品推荐

