我有一个很大的数据表,包含许多时间依赖变量(50+),用于coxph模型。这个数据集是使用tmerge生成的。患者由patid变量标识,时间间隔由tstart和tstop定义。
我想要拟合的大多数模型仅使用这些时间相关变量中的一个选择。遗憾的是,考克斯比例风险模型的速度取决于数据表中的行数和时间点数,即使这些行中的所有数据都相同。是否有一种好/快的方法可以合并除时间间隔外相同的行,以加快模型的速度?在许多情况下,一行的tstop等于下一行的tstart,在移除一些列之后,其它一切都相同。
例如,我想将data.table示例转换为结果。
library(data.table)
example=data.table(patid = c(1,1,1,2,2,2), tstart=c(0,1,2,0,1,2), tstop=c(1,2,3,1,2,3), x=c(0,0,1,1,2,2), y=c(0,0,1,2,3,3))
results=data.table(patid = c(1,1,2,2), tstart=c(0,2,0,1), tstop=c(2,3,1,3), x=c(0,1,1,2), y=c(0,1,2,3))
这个例子非常简单。我当前的数据集有大约60万名患者,超过20 M行和3.65万个时间点。删除变量应该会显著减少所需的行数,这应该会显著提高使用变量子集进行模型拟合的速度。
我能想到的最好的办法是:
example=data.table(patid = c(1,1,1,2,2,2), tstart=c(0,1,2,0,1,2), tstop=c(1,2,3,1,2,3), x=c(0,0,1,1,2,2), y=c(0,0,1,2,3,3))
example = example[order(patid,tstart),]
example[,matched:=x==shift(x,-1)&y==shift(y,-1),by="patid"]
example[is.na(matched),matched:=FALSE,by="patid"]
example[,tstop:=ifelse(matched,shift(tstop,-1),tstop)]
example[,remove:=tstop==shift(tstop),by="patid"]
example = example[is.na(remove) | remove==FALSE,]
example$matched=NULL
example$remove=NULL
这解决了这个例子;然而,这是相当复杂和多余的代码,当我在数据集中有许多列必须编辑x==shift时(x,-1)为每个变量都是在请求错误。有没有理智的方法来做这件事?列的列表会根据循环改变很多次,因此接受一个列名向量作为输入进行比较将是理想的。t科普一行中包含相同协变量值的多个时段(例如,具有相同协变量值的时段(0,1)、(1,3)、(3,4))
3条答案
按热度按时间6l7fqoea1#
此解决方案基于
x
和y
组合的rleid()
创建temp
永久组ID。使用此临时值,然后将其删除(temp := NULL
)vq8itlhq2#
下面是一个基于我们上面的对话/评论的选项,但允许灵活地设置向量列名:
输出:
mnowg1ta3#
基于Wimpel的回答,我创建了下面的解决方案,它也允许使用列名向量作为输入。
我可以想象这可以简化,但我认为它做了更复杂的示例所需要的。