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

R语言数据处理:按规则生成latest_discharge_date列提取最大后续日期

问题:生成符合规则的latest_discharge_date列

样本数据

data <- data.frame(
  year = c(2018, 2018, 2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020),
  patient_id = c(101, 102, 103, 104, 102, 102, 106, 105, 105, 107, 108, 109, 105, 105, 201, 202, 203, 204, 205, 205, 205, 209, 208),
  discharge_date = as.Date(c("1/1/2018", "1/5/2018", "1/8/2018", "2/5/2018", "2/10/2018", "2/11/2018", "3/1/2018", "1/2/2019", "1/10/2019", "3/1/2019", "3/5/2019", "3/25/2019", "5/5/2019", "5/6/2019", "1/1/2020", "2/1/2020", "2/10/2020", "3/3/2020", "4/1/2020", "4/2/2020", "4/3/2020", "6/17/2020", "8/8/2020"), format = "%m/%d/%Y"),
  contagious_admission = c(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0)
)

需求说明

需要创建latest_discharge_date列,取值规则如下:

  • 若当前行的patient_id与后续行的patient_id不同,则取当前行的discharge_date;
  • 若当前行与后续行的patient_id相同,且两行的contagious_admission均为0,则取当前行的discharge_date;
  • 若同一patient_id存在连续的后续行,且该系列首行的contagious_admission为0,后续行的contagious_admission为1,则首行的latest_discharge_date需取这些后续行中的最大discharge_date。

第一次尝试及问题

data |>
  mutate(
    latest_discharge_date = case_when(
      contagious_admission == 0 & lead(contagious_admission) == 0 ~ discharge_date,
      contagious_admission == 0 & lead(contagious_admission) == 1 ~ lead(discharge_date)
    , TRUE ~ NA)
  )

该代码在多数情况下正常运行,但针对patient_id = 205,其contagious_admission == 0的行对应的latest_discharge_date取了"2020-04-02",而实际需要取该患者后续contagious_admission == 1组中的最大日期"2020-04-03"。

第二次尝试及问题

data |>
  mutate(
    latest_discharge_date = case_when(
      contagious_admission == 0 & lead(contagious_admission) == 0 ~ discharge_date,
      contagious_admission == 0 & lead(contagious_admission) == 1 ~ lead(pmax(lead(discharge_date)))
    , TRUE ~ NA)
  )

该代码能正确处理多个后续contagious_admission == 1的行,但会在单个后续行的场景下出现错误。

解决方案

要解决这个问题,我们可以按patient_id分组,标记每个0值行对应的后续1值行组,再提取组内最大日期。具体代码如下:

library(dplyr)
library(tidyr)

data_processed <- data |>
  group_by(patient_id) |>
  # 标记当前0值行是否紧跟1值行
  mutate(
    is_leading_zero = contagious_admission == 0 & lead(contagious_admission, default = 0) == 1,
    # 将前置0行和后续1值行归为同一组
    group_id = ifelse(is_leading_zero, row_number(), NA),
    group_id = fill(group_id, .direction = "down")
  ) |>
  # 计算每个组内1值行的最大出院日期
  mutate(max_contagious_date = ifelse(!is.na(group_id), max(discharge_date[contagious_admission == 1]), NA)) |>
  # 按规则生成目标列
  mutate(
    latest_discharge_date = case_when(
      # 规则1:当前是患者最后一行
      row_number() == n() ~ discharge_date,
      # 规则3:前置0行取对应1值组的最大日期
      is_leading_zero ~ max_contagious_date,
      # 规则2:当前和后续都是0,取当前日期
      contagious_admission == 0 & lead(contagious_admission) == 0 ~ discharge_date,
      # 1值行设为NA(可按需调整)
      TRUE ~ NA
    )
  ) |>
  # 清理临时列
  select(-is_leading_zero, -group_id, -max_contagious_date) |>
  ungroup()

print(data_processed)

代码说明

  1. 分组处理:按patient_id分组,确保仅处理同一患者的行;
  2. 标记关联组:用fill将前置0行的标记向下传递,把它和后续的1值行绑定为同一组;
  3. 计算组内最大值:针对每个关联组,提取其中1值行的最大出院日期;
  4. 规则匹配赋值:严格对应三条需求规则赋值,覆盖所有场景。

运行后,patient_id=205的0值行将正确取到2020-04-03,单个后续1值行的场景也能正常工作。


内容的提问来源于stack exchange,提问作者Mahm00d27

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:47:06