基于EXSTDAY与EXSTPDAY展开长格式数据集的技术问询
实现按日期区间展开观测记录的R方案
需求说明
针对数据集中的每个ID,将EXSTDAY到EXSTPDAY区间内的每一天生成单独的观测行,同时保留ID、DOSEA、DOSFRM、DOSFRQ字段。
示例数据集
假设你的原始数据结构如下(基于你提供的dput逻辑):
df <- structure(list( ID = c(1, 2), EXSTDAY = c(3, 5), EXSTPDAY = c(7, 8), DOSEA = c(100, 200), DOSFRM = c("Tablet", "Injection"), DOSFRQ = c("Daily", "BID") ), class = "data.frame", row.names = c(NA, -2L))
方案1:使用tidyverse(dplyr + tidyr)
适合常规规模数据集,代码可读性强:
library(tidyverse) # 按ID及需保留的字段分组,生成日期序列并展开 expanded_df <- df %>% group_by(ID, DOSEA, DOSFRM, DOSFRQ) %>% reframe(STDAY = seq(EXSTDAY, EXSTPDAY, by = 1)) %>% ungroup() # 查看结果 print(expanded_df)
方案2:使用data.table
适合大规模数据集,运行效率更高:
library(data.table) # 转换为data.table格式 setDT(df) # 按指定字段分组,生成日期序列并展开 expanded_dt <- df[, .(STDAY = seq(EXSTDAY, EXSTPDAY, by = 1)), by = .(ID, DOSEA, DOSFRM, DOSFRQ)] # 可选:转换回data.frame格式 expanded_df <- as.data.frame(expanded_dt)
预期输出示例
运行后将得到符合需求的展开数据:
ID DOSEA DOSFRM DOSFRQ STDAY 1 1 100 Tablet Daily 3 2 1 100 Tablet Daily 4 3 1 100 Tablet Daily 5 4 1 100 Tablet Daily 6 5 1 100 Tablet Daily 7 6 2 200 Injection BID 5 7 2 200 Injection BID 6 8 2 200 Injection BID 7 9 2 200 Injection BID 8
注意事项
- 若原始数据中
EXSTDAY或EXSTPDAY存在缺失值,需先过滤:df %>% filter(!is.na(EXSTDAY) & !is.na(EXSTPDAY)) - 如果你的日期是标准日期格式(而非数字天数),将
seq替换为seq.Date即可适配。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

