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

时间:2017-01-30 18:22:06

标签: r reshape survival-analysis 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) 

感谢您的任何建议。

1 个答案:

答案 0 :(得分:1)

考虑以下数据与基础R争论,其中基本上你merge数据框本身移动了一行以对齐当前和下一条记录,然后transform开始和< em>停止计算。

注意:merge会引发重复的nextidcnt列的警告(而不是错误)。使用data1id(在新df中移位一个)作为连接键忽略或创建合并的第二个idcnt

# 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