You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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值,分组内第一行返回NA
  • coalesce(..., 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 22:36:03