如何基于个体ID创建并统计连续数值序列时段(适配日期)
合并连续时段数据集的解决方案
问题描述
现有包含个体ID(enrolid)、起始数值(start)、结束数值(end)的数据集,需要生成个体-时段级别的连续时段数据集。连续时段定义为:当前行的start ≤ 上一行的end + 1,满足该条件的行需合并为一个连续时段,取合并组内最小的start和最大的end作为新时段的起止值,并为每个个体的连续时段生成序号。
现有数据:
have <- tibble( enrolid = c(1,1,1,1,2,2,2,2), start = c(0,11,19,24,2,14,17,37), end = c(10,15,25,29,13,16,35,49) )
期望结果:
want <- tibble( enrolid = c(1,1,2,2), continuous_cov_start = c(0,19,2,37), continuous_cov_end = c(15,29,35,49), continuous_cov_sequence = c(1,2,1,2) )
注:当前使用数值类型的start和end,后续需适配为日期类型,目标是生成唯一的连续保险覆盖时段数据集。
解决方案(使用tidyverse工具链)
用dplyr的分组、窗口函数即可实现,无需循环,代码简洁且适配后续日期类型需求:
library(dplyr) want <- have %>% # 按个体ID分组,确保每个个体的时段按start排序(核心前提,避免顺序错乱) group_by(enrolid) %>% arrange(start, .by_group = TRUE) %>% # 标记新时段:当前行start超过上一行end+1时,视为新时段起点 mutate(new_period = if_else(start > lag(end, default = -Inf) + 1, 1, 0)) %>% # 累加标记值,生成每个个体内的连续时段分组ID mutate(continuous_cov_sequence = cumsum(new_period) + 1) %>% # 按个体ID和时段ID聚合,取组内最小start和最大end group_by(enrolid, continuous_cov_sequence) %>% summarise( continuous_cov_start = min(start), continuous_cov_end = max(end), .groups = "drop" )
代码解释
- 分组排序:先按
enrolid分组,再按start排序,确保每个个体的时段按数值/时间顺序排列,这是合并连续时段的基础。 - 标记新时段:用
lag()获取上一行的end值,判断当前行start是否超出上一行end+1,是则标记为新时段(new_period=1)。default=-Inf是为了处理每个个体的第一行,确保第一行被识别为新时段起点。 - 生成时段序号:对
new_period做累加(cumsum)后加1,得到每个个体内的连续时段序号。 - 聚合合并:按
enrolid和时段序号分组,取组内最小start作为连续时段起始,最大end作为结束。
适配日期类型的说明
如果后续将start和end改为日期类型(如Date或POSIXct),只需确保日期格式正确,上述代码无需修改——dplyr的比较运算符、lag()、min()/max()对日期类型同样适用。示例:
# 模拟日期类型数据 have_date <- tibble( enrolid = c(1,1), start = as.Date(c("2020-01-01", "2020-01-11")), end = as.Date(c("2020-01-10", "2020-01-15")) ) # 用相同代码处理 have_date %>% group_by(enrolid) %>% arrange(start, .by_group = TRUE) %>% mutate(new_period = if_else(start > lag(end, default = as.Date("1900-01-01")) + 1, 1, 0)) %>% mutate(continuous_cov_sequence = cumsum(new_period) + 1) %>% group_by(enrolid, continuous_cov_sequence) %>% summarise( continuous_cov_start = min(start), continuous_cov_end = max(end), .groups = "drop" )
内容的提问来源于stack exchange,提问作者Pharmepi
相关产品推荐
相关产品推荐

