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

如何将患者随访时间按月拆分,每月对应一行数据?

问题:将随访时间区间按月拆分生成每行对应一个月的数据

我有一项观察性研究的数据,包含每位患者的随访起止时间,希望把时间区间按月拆分,每个月对应一行数据。

原始数据框

df <- data.frame(
  PATIENT = c(1,2, 3, 4),
  Start = c("2016-01-01", "2017-12-01", "2016-03-01", "2016-02-01"),
  End = c("2016-05-30","2018-01-30","2016-06-30","2016-05-30")
)

期望输出数据框

data.frame(
  PATIENT = c(1,1,1,1,2,2,3,3,3,3,4,4,4,4),
  PERIOD = c("2016-01-01", "2016-02-01", "2016-03-01", "2016-04-01", "2016-05-01",
              "2017-12-01","2018-01-01",
              "2016-03-01","2016-04-01","2016-05-01","2016-06-01",
              "2016-02-01","2016-03-01","2016-04-01","2016-05-01")
)

说明

做此处理是为了使用TrialEmulation包——一款用于观察性数据模拟试验的新工具,曾尝试使用tmerge和TimeSplitter,但均未得到预期结果。


解决方案

可以用tidyverse结合lubridate包实现,步骤如下:

  1. 加载所需包:
library(tidyverse)
library(lubridate)
  1. 数据处理代码:
df_processed <- df %>%
  # 转换为日期格式
  mutate(Start = ymd(Start), End = ymd(End)) %>%
  # 为每个患者生成从随访起始月到结束月的每月第一天序列
  mutate(PERIOD = map2(
    floor_date(Start, "month"),
    floor_date(End, "month"),
    ~seq(.x, .y, by = "month")
  )) %>%
  # 展开列表为多行
  unnest(PERIOD) %>%
  # 转换为字符格式匹配期望输出
  mutate(PERIOD = as.character(PERIOD)) %>%
  # 保留所需列
  select(PATIENT, PERIOD)

运行后得到的df_processed即为符合要求的输出。

代码解释

  • floor_date():将起止日期转为当月第一天,确保序列从每个月的起始点生成
  • map2():对每行的起止月份配对生成月度序列
  • unnest():将嵌套的列表列展开为多行数据,实现按月拆分的效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:30:07