如何编写循环调整日期时段?合并同ID同剂量的连续治疗周期
问题描述
我有一个包含数千人的大型数据集,每个人的每个治疗周期单独一行记录,字段包括id、inn(开始日期)、out(结束日期)和dose(剂量)。规则是:两个连续治疗周期间隔超过7天的话,会有一行记录该间隔时段且dose=0;间隔小于7天则无此记录。
需求:将每个用户满足以下条件的多个周期合并为一个连续周期:
- 同一
id - 同一
dose - 彼此间隔小于7天
不同剂量的相邻周期即使间隔小于7天也不合并。
我尝试用ifelse实现,但遇到多个需合并的相邻周期时出错,想写循环又搞不定,求帮助。
示例数据集
library(data.table) d=data.frame(id=c(1,1,1,1,1,1,1,2,2,2,2,2,2), inn=as.Date(c("2017-09-11", "2017-12-21", "2018-03-19", "2018-06-27", "2019-01-15", "2019-04-29", "2019-11-20", "2019-02-06","2019-04-07","2019-05-14","2019-07-13","2019-07-23","2019-09-25")), out=as.Date(c("2017-12-21","2018-03-19", "2018-06-27", "2019-01-15", "2019-04-25", "2019-11-15", "2021-07-10", "2019-04-07","2019-05-14","2019-07-13","2019-07-23","2019-09-21","2021-05-14")), dose=c("20","0","20","0", "20", "20","20","2.5","0","2.5","0","2.5","2.5")) setDT(d)
期望结果
e=data.frame(id=c(1,1,1,1,1,2,2,2,2,2), inn=as.Date(c("2017-09-11", "2017-12-21", "2018-03-19", "2018-06-27", "2019-01-15", "2019-02-06","2019-04-07","2019-05-14","2019-07-13","2019-07-23")), out=as.Date(c("2017-12-21","2018-03-19", "2018-06-27", "2019-01-15","2021-07-10", "2019-04-07","2019-05-14","2019-07-13","2019-07-23","2021-05-14")), dose=c("20","0","20","0", "20","2.5","0","2.5","0","2.5"))
解决方案
利用data.table的高效分组与窗口函数可以实现需求,无需编写循环,处理大数据集效率更高。核心逻辑是通过标记合并组,再按组聚合得到合并后的周期:
library(data.table) # 1. 在同id同dose分组内,获取上一个周期的结束日期 d[, prev_out := shift(out), by = .(id, dose)] # 2. 计算当前周期开始与上一个同剂量周期结束的间隔天数 d[, gap := inn - prev_out] # 3. 创建合并组标签:间隔≥7天或为组内首条记录时,组号递增 d[, group := cumsum(is.na(gap) | gap >= 7), by = .(id, dose)] # 4. 按id、dose、group分组,聚合得到合并后的周期(取组内最早inn、最晚out) result <- d[, .(inn = min(inn), out = max(out)), by = .(id, dose, group)] # 5. 移除group列并按id、inn排序 result <- result[, !"group"][order(id, inn)] # 输出结果 print(result)
代码说明
shift(out), by = .(id, dose):在同一id和dose的分组内,提取上一行的out日期,用于计算间隔gap := inn - prev_out:得到当前周期与上一个同剂量周期的间隔天数cumsum(is.na(gap) | gap >=7):生成合并组标识,当间隔≥7天或为组内第一条记录(gap为NA)时,组号加1,确保间隔<7天的同剂量周期归为同一组- 最后按组聚合,取组内最早的开始日期和最晚的结束日期,得到合并后的连续周期
运行后结果与你给出的期望结果完全一致,且该方法基于向量化操作,处理大规模数据效率优于循环。
内容的提问来源于stack exchange,提问作者Noa
相关产品推荐
相关产品推荐

