【发布时间】:2014-11-12 15:07:28
【问题描述】:
由于我用于多状态分析(传记)的包的格式要求,我需要使用我的受访者的状态序列生成一个路径变量(字符变量)。
这可以使用 Biograph 包中提供的函数“Sequences.ind.0”轻松完成,但由于循环,该函数效率非常低:我的实际数据库需要 20 多个小时(大约 500 万条记录)。我不知道如何在没有循环或更快的情况下获得相同的结果。
这里我展示了一个包含三个状态(N、P、K)的简单示例,其中 K 是吸收状态(即在 K 之后没有额外的跃迁)
dat <- data.table(ID=c(1:5),
K=c(NA, 2005, 2004, 2001, 2006),
P=c(2001, 1999, 2003, 2003, 1998),
P=c(2005, 2001, NA, NA, 2001),
P=c(NA, 2003, NA, NA , 2004),
N=c(2002, 2000, NA, 2003,2000),
N=c(NA, 2002, NA, NA, 2003),
N=c(NA, NA, NA, NA, 2005))
我想获得每个人的状态路径和一个随着状态变化发生的时间的矩阵。 “N”是初始状态,所以每个序列都应该以“N”开头。之后,状态序列由转换发生的时间给出。
如果我使用函数“Sequences.ind.0”,我会得到:
library(Biograph)
nsample <- nrow(dat)
namstates <- c("N", "P", "K")
f <- Sequences.ind.0(as.matrix(dat[, 2:8, with=FALSE]),namstates,absorb="K")
$namstates
[1] "N" "P" "K"
$d
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 2001 2002 2005 NA NA NA NA
[2,] 1999 2000 2001 2002 2003 2005 NA
[3,] 2003 2004 NA NA NA NA NA
[4,] 2001 NA NA NA NA NA NA
[5,] 1998 2000 2001 2003 2004 2005 2006
$path
[1] "NPNP" "NPNPNPK" "NPK" "NK" "NPNPNPNK"
最重要的输出是“path”和“d”。 在这种情况下,是否有人对如何使用 data.table 或其他方法避免循环有任何想法/建议?提前致谢!
【问题讨论】:
-
澄清一下:基本算法类似于“1)对每一行进行排序。2)对于行中的每个条目,检查年份并记录其对应列的名称(N,P,或 K)"。对吗?
-
是的!我要补充一点,如果 K 发生(吸收状态,例如死亡),人们可能会忘记这一年剩下的时间和姓名记录。事后这样做可能更有效率。我不知道。
-
我没有很好的答案,但似乎这不是适合这项工作的数据结构
-
什么是更好的数据结构?
-
最好有一个像
list(K=c(2001, 2004, 2005, 2006), ...)这样的年份和状态的“字典”,但这不是我确定的。我编辑了一个data-structures标签,也许可以从该领域的专家那里获得一些意见。
标签: r loops data-structures data.table