R使用survSplit重塑/扩展数据集以获得cox回归的时变变量

R reshaping / expanding dataset using survSplit to obtain time-varying variable for cox regression

我看过其他类似的问题,但他们没有回答我的问题。我想扩展我的数据集,因为我需要为生存分析创建一个时变变量,并想使用 survSplit 命令(survival 包),但我的数据已经部分采用长格式。示例数据:

data1<-structure(list(id = c(1, 1, 1, 1, 5, 5, 5, 5, 5, 7, 7, 7, 7, 
7, 7), start = c(0, 183, 210, 241, 0, 183, 187, 212, 244, 0, 
118, 139, 188, 212, 237), no_days = c(NA, 28L, 28L, 28L, NA, 
7L, 28L, 28L, 28L, NA, 28L, 28L, 28L, 28L, 28L), stop = c(NA, 
211, 238, 269, NA, 190, 215, 240, 272, NA, 146, 167, 216, 240, 
265), drug = c(0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1), 
    dead = c(0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)), .Names = c("id", 
"start", "no_days", "stop", "drug", "dead"), row.names = c(NA, 
15L), class = "data.frame")

> head(data1,15)
   id start no_days stop drug dead
1   1     0      NA   NA    0    0
2   1   183      28  211    1    0
3   1   210      28  238    1    0
4   1   241      28  269    1    1
5   5     0      NA   NA    0    0
6   5   183       7  190    1    0
7   5   187      28  215    1    0
8   5   212      28  240    1    0
9   5   244      28  272    1    1
10  7     0      NA   NA    0    0
11  7   118      28  146    1    0
12  7   139      28  167    1    0
13  7   188      28  216    1    0
14  7   212      28  240    1    0
15  7   237      28  265    1    1

Start 是开药的日期,no_days 是开药的时间,drug 表示一个人是否在给定的时间段内服药(这是我需要随时间变化的变量),dead 表示一个人何时死亡。目前数据集只包含一个人服用药物的时间,所以我想要的最终数据集应该是这样的:

 head(data1,18)
   id start no_days stop drug dead
1   1     0      NA  182    0    0
2   1   183      28  211    1    0
3   1   210      28  238    1    0
4   1   239      NA  240    0    0
5   1   241      28  269    1    1
6   5     0      NA  182    0    0
7   5   183       7  190    1    0
8   5   187      28  215    1    0
9   5   212      28  240    1    0
10  5   241      NA  243    0    0
11  5   244      28  272    1    1
12  7     0      NA  117    0    0
13  7   118      28  146    1    0
14  7   139      28  167    1    0
15  7   168      NA  187    0    0
16  7   188      28  216    1    0
17  7   212      28  240    1    0
18  7   237      28  265    1    1

也许这应该是一个标准的数据操作问题,我需要根据特定条件添加更多行,但考虑到它是生存数据,survSplit 就是为此而设计的,尽管数据结构略有不同首先,我想知道是否有一种简单的方法可以使用 survSplit 来解决我的问题。如果没有,有没有人有一个简单的建议来扩展数据框。

我的最终步骤是拟合 cox 模型,例如:

coxph(Surv(data$start,data$stop,data$dead)~covariates + drug +cluster(id),data=data1) 

感谢您的任何建议。

考虑以下与基数 R 的数据争论,其中本质上你 merge 数据帧本身移动一行以对齐当前和下一条记录,然后 transform 用于 start停止计算。

注意:merge 将对重复的 nextidcnt 列发出警告(不是错误)。使用 ididcnt(在新 df 中移动一个)作为连接键,忽略或为合并创建第二个 data1

# OBTAIN GROUP COUNT (FOR MERGE IDs)
data1$idcnt <- sapply(1:nrow(data1), function(i) sum(data1[1:i, c("id")] == data1$id[i]))
data1$nextidcnt <- data1$idcnt + 1

# MERGE
dfm <- merge(data1, data1, by.x=c("id", "nextidcnt"), by.y=c("id", "idcnt"))

# CALCULATE NEW COLUMNS
dfm <- transform(dfm,
                 start = ifelse(is.na(stop.x), start.x, stop.x + 1),
                 no_days = no_days.x,
                 stop = start.y - 1,
                 drug = 0,
                 dead = dead.x)  

# ROW BIND ORIGINAL SUBSET WITH NEW ROWS
finaldf <- rbind(data1[data1$start != 0, c(1:6)],
                 dfm[dfm$start < dfm$stop,
                     c("id", "start", "no_days", "stop", "drug", "dead")])

finaldf <- finaldf[with(finaldf, order(id, start, stop)),]  # ORDER BY ID, START, STOP
rownames(finaldf) <- NULL                                   # RESET ROW NAMES

输出

finaldf

#    id start no_days stop drug dead
# 1   1     0      NA  182    0    0
# 2   1   183      28  211    1    0
# 3   1   210      28  238    1    0
# 4   1   239      28  240    0    0
# 5   1   241      28  269    1    1
# 6   5     0      NA  182    0    0
# 7   5   183       7  190    1    0
# 8   5   187      28  215    1    0
# 9   5   212      28  240    1    0
# 10  5   241      28  243    0    0
# 11  5   244      28  272    1    1
# 12  7     0      NA  117    0    0
# 13  7   118      28  146    1    0
# 14  7   139      28  167    1    0
# 15  7   168      28  187    0    0
# 16  7   188      28  216    1    0
# 17  7   212      28  240    1    0
# 18  7   237      28  265    1    1