R语言计算数据集每条记录对应上一次患病结束日期的方法咨询
实现方案(tidyverse生态)
核心用到窗口函数lag(),配合分组操作即可实现需求,代码简洁且性能足以支撑数万条数据集的处理。
完整代码
library(tidyverse) # 多人员测试数据集 sick <- tribble( ~ID, ~RecordBegins, ~SickStartDate, ~SickEndDate, "person1", as.Date("1990-01-01"), as.Date("2017-03-04"), as.Date("2017-07-01"), "person1", as.Date("1990-01-01"), as.Date("2018-11-01"), as.Date("2019-02-04"), "person2", as.Date("1995-01-01"), as.Date("2014-10-07"), as.Date("2017-01-04"), "person2", as.Date("1995-01-01"), as.Date("2017-11-01"), as.Date("2017-11-23"), ) # 核心处理逻辑 sick_processed <- sick %>% # 先按人员ID、患病起始日期排序,保证同人员的记录按时间先后顺序排列 arrange(ID, SickStartDate) %>% # 按人员ID分组,各组独立计算 group_by(ID) %>% # 生成目标列:取上一次患病的结束日期,首次患病则取记录起始日期填充 mutate(EndLastSick = coalesce(lag(SickEndDate), RecordBegins)) %>% # 取消分组,避免后续操作受分组影响 ungroup()
逻辑说明
arrange(ID, SickStartDate):避免原始数据中同人员的患病记录顺序混乱,确保lag()取到的是时间上真正的上一次患病结束日期group_by(ID):按人员拆分计算,不同人员的记录不会互相干扰lag(SickEndDate):窗口函数,取分组内上一行的SickEndDate值,分组内第一行返回NAcoalesce(..., RecordBegins):将NA值(即首次患病的行)替换为对应人员的RecordBegins
运行结果
输出的sick_processed如下,完全符合需求:
# A tibble: 4 × 5 ID RecordBegins SickStartDate SickEndDate EndLastSick <chr> <date> <date> <date> <date> 1 person1 1990-01-01 2017-03-04 2017-07-01 1990-01-01 2 person1 1990-01-01 2018-11-01 2019-02-04 2017-07-01 3 person2 1995-01-01 2014-10-07 2017-01-04 1995-01-01 4 person2 1995-01-01 2017-11-01 2017-11-23 2017-01-04
内容的提问来源于stack exchange,提问作者AndrewT
相关产品推荐
相关产品推荐

