在R中重塑复杂时间-事件数据:转换为带累积事件状态的时间序列表
R实现方案
核心实现逻辑:
- 为每个个体生成全随访周期的时间节点,节点范围覆盖随访起始时间、所有事件发生时间、随访结束时间
- 事件状态按时间累计取最大值,保证事件一旦触发则永久保持为1
依赖准备
需使用tidyverse系列包,首次运行先安装并加载:
# 安装包(首次运行执行) install.packages("tidyverse") # 加载包 library(tidyverse)
分步实现代码
- 第一步:准备原始数据(可直接替换为你的实际df,无需重新构造)
df <- data.frame( id = c(1,1,2,2,2,2), Date = c(2,3,3,6,7,2), Start_Date = c(1,1,2,2,2,2), End_Date = c(4,4,9,9,9,9), A = c(1,0,1,1,1,0), B = c(0,1,0,0,0,1) )
- 第二步:提取每个个体的随访起止配置(同一id的Start/End固定,去重提取)
id_followup <- df %>% select(id, Start_Date, End_Date) %>% distinct()
- 第三步:生成所有个体的去重时间节点列表
time_nodes <- df %>% # 保留原始事件发生时间 select(id, Date) %>% # 绑定每个个体的随访起始时间为节点 bind_rows(id_followup %>% mutate(Date = Start_Date) %>% select(id, Date)) %>% # 绑定每个个体的随访结束时间为节点 bind_rows(id_followup %>% mutate(Date = End_Date) %>% select(id, Date)) %>% # 同一id下时间去重、按升序排列 group_by(id) %>% distinct(Date) %>% arrange(Date, .by_group = T) %>% ungroup() %>% # 重命名为目标变量Time rename(Time = Date)
- 第四步:整理原始事件数据(处理同一时间点多个事件的情况)
raw_events <- df %>% select(id, Date, A, B) %>% arrange(id, Date) %>% group_by(id, Date) %>% # 同一时间点若同时触发多个事件,取最大值保证状态正确 summarise(across(c(A,B), max), .groups = "drop")
- 第五步:关联时间节点与事件状态,计算累计事件值
Cool_df <- time_nodes %>% # 左连接事件表,未发生事件的时间点初始填充0 left_join(raw_events, by = c("id" = "id", "Time" = "Date")) %>% mutate(across(c(A,B), ~replace_na(.x, 0))) %>% group_by(id) %>% # 按时间累计取最大值,保证事件触发后状态永久为1 mutate( A = cummax(A), B = cummax(B) ) %>% ungroup()
结果验证
运行Cool_df即可得到与示例完全一致的输出:
# A tibble: 9 × 4 id Time A B <dbl> <dbl> <dbl> <dbl> 1 1 1 0 0 2 1 2 1 0 3 1 3 1 1 4 1 4 1 1 5 2 2 0 1 6 2 3 1 1 7 2 6 1 1 8 2 7 1 1 9 2 9 1 1
内容的提问来源于stack exchange,提问作者Economist_Ayahuasca
相关产品推荐
相关产品推荐

