使用R按ID及自定义双周周期分组事件日期的技术问询
基于ID首个事件日期的双周全局分组实现
我明白你需要的是每个ID以自身首个事件日期为起点划分双周周期,同时生成全局唯一的分组编号。下面用R语言结合dplyr包来实现这个需求,完全匹配你给出的示例格式。
示例数据整理
先把你提供的示例数据补全为可直接运行的格式:
dat <- structure( list( ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L), Date = structure( c(17532, 17533, 17533, 17563, 17591, 17532, 17622), class = "Date" ) ), row.names = c(NA, -7L), class = "data.frame" )
实现步骤
我们可以分两步完成:先为每个ID计算内部的双周组号,再将这些内部组号转换为全局唯一的连续编号。
library(dplyr) # 1. 按ID分组,计算每个ID的起始日期与内部双周组号 dat_with_groups <- dat %>% group_by(ID) %>% mutate( # 获取当前ID的首个事件日期(双周周期起点) start_date = min(Date), # 计算当前日期与起点的天数差 days_diff = as.integer(Date - start_date), # 生成内部双周组号:0-13天为第1组,14-27天为第2组,以此类推 internal_group = floor(days_diff / 14) + 1 ) %>% ungroup() # 2. 将ID+内部组的组合转换为全局唯一的连续分组编号 final_dat <- dat_with_groups %>% mutate( # 生成唯一组标识 unique_group_key = paste(ID, internal_group, sep = "_"), # 把唯一标识转为连续整数,得到全局分组号 Group = as.integer(factor(unique_group_key, levels = unique(unique_group_key))) ) %>% # 保留需要的列 select(ID, Date, Group)
运行结果
执行上述代码后,final_dat的输出完全符合你的示例要求:
# A tibble: 7 × 3 ID Date Group <int> <date> <int> 1 1 2018-01-01 1 2 1 2018-01-02 1 3 1 2018-01-02 1 4 1 2018-02-01 2 5 1 2018-03-01 3 6 2 2018-01-01 4 7 2 2018-04-01 5
关键逻辑说明
- 独立周期计算:通过
group_by(ID)确保每个ID的双周周期从自身首个事件日期开始,不会和其他ID的周期混淆。 - 双周分组规则:
floor(days_diff / 14) + 1保证每个周期严格为14天,起始日所在的14天为第1组。 - 全局唯一编号:利用
factor的特性,将不同ID的内部组映射为全局连续的整数,实现跨ID的唯一分组标识。
内容的提问来源于stack exchange,提问作者A. Kang
相关产品推荐
相关产品推荐

