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
列发出警告(不是错误)。使用 id
和 idcnt
(在新 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
我看过其他类似的问题,但他们没有回答我的问题。我想扩展我的数据集,因为我需要为生存分析创建一个时变变量,并想使用 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
列发出警告(不是错误)。使用 id
和 idcnt
(在新 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