R语言带条件日期滞后处理:提取重叠时间序列的最新结束日期
解决方法
你的需求其实可以通过追踪每个个体的累积最大结束日期来实现,不需要循环——用dplyr结合purrr的accumulate函数就能高效完成,完美复现你要的target_date列。
核心逻辑
对于每个按id和start_date排序的个体:
- 第一行的
target_date设为NA; - 从第二行开始,
target_date等于截至上一行的最大结束日期; - 同时更新当前的最大结束日期为「上一行的最大结束日期」和「当前行结束日期」的较大值——这样后续行能自动继承最新的有效最大结束日期。
完整代码
library(dplyr) library(purrr) # 你的示例数据 id <- c("A","A","A","A","A","A","A","A","A","A", "A","A","A","B","B","B","B","B","B") start_date <- as.Date(c("2004-01-23","2005-03-31","2005-03-31","2005-12-20","2005-12-20", "2006-04-03","2007-11-26","2010-10-12","2011-08-08","2012-06-26", "2012-06-26","2012-09-11","2012-10-03","2003-12-01","2006-02-28", "2012-04-16","2012-08-30","2012-09-19","2012-09-28")) end_date <- as.Date(c("2009-06-30","2005-09-17","2005-09-19","2005-12-30","2005-12-30", "2006-06-19","2009-06-30","2010-11-05","2011-11-18","2012-06-26", "2012-06-26","2012-09-11","2014-04-01","2012-08-29","2006-02-28", "2012-04-16","2012-09-28","2013-10-11","2013-07-19")) df <- data.frame(id, start_date, end_date) # 生成target_date df_final <- df %>% arrange(id, start_date) %>% group_by(id) %>% mutate( # 累积计算每个步骤的最大结束日期 current_max_end = accumulate(end_date, .init = first(end_date), ~ max(.x, .y)), # target_date是上一步的最大结束日期,第一行自动为NA target_date = lag(current_max_end) ) %>% ungroup() %>% select(id, start_date, end_date, target_date) # 查看结果 print(df_final)
结果验证
运行后生成的target_date完全和你提供的示例一致:
- 比如
id=A的第8行,start_date超过了之前的最大结束日期(2009-06-30),所以target_date就是这个值,同时更新最大结束日期为当前行的2010-11-05; id=B的第5行,start_date在之前的最大结束日期(2012-09-28)范围内,target_date就是这个值,同时因为当前行的end_date更大,更新最大结束日期为2013-10-11,第6行的target_date就继承了这个新值。
这个方法是向量式操作,比循环高效得多,而且不需要重复执行就能一次性完成所有处理。
内容的提问来源于stack exchange,提问作者TimL
相关产品推荐
相关产品推荐

