以区间格式重新整形宽数据集

时间:2013-01-26 17:38:16

标签: r reshape

我正在开发一个“宽”数据集,现在我想使用一个特定的包(-msSurv-,用于非参数多态模型),它需要间隔形式的数据。

我的当前数据集的特征是每个人占一行:

dat <- read.table(text = "

   id    cohort   t0    s1     t1     s2      t2     s3    t3
    1      2      0      1     50      2      70     4     100
    2      1      0      2     15      3      100    0     0   

", header=TRUE)

其中cohort是时间固定的协变量,s1 - s3对应时变协变量s = 1,2,3,4随时间变化的值(它们是个人随时间访问的不同国家)。日历时间由t1 - t3定义,每个人的0100不等。

因此,例如,个人1保持在状态= 1直到日历时间= 50,然后他保持状态= 2直到时间= 70,最后他保持状态= 4直到时间100。

我想要获得的是“间隔”形式的数据集,即:

id   cohort  t.start    t.stop   start.s   end.s          
1      2        0         50        1        2
1      2       50         70        2        4
1      2       70        100        4        4
2      1        0         15        2        3
2      1       15        100        3        3

我希望这个例子足够清楚,否则请告诉我,我会尝试进一步澄清。

您如何自动化这种重塑?考虑到我有相对大量的(模拟)个体,大约100万。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:6)

我想我明白了。这有用吗?

require(data.table)
dt <- data.table(dat, key=c("id", "cohort"))
dt.out <- dt[,  list(t.start=c(t0,t1,t2), t.stop=c(t1,t2,t3), 
                     start.s=c(s1,s2,s3), end.s=c(s2,s3,s3)), 
                     by = c("id", "cohort")]

#    id cohort t.start t.stop start.s end.s
# 1:  1      2       0     50       1     2
# 2:  1      2      50     70       2     4
# 3:  1      2      70    100       4     4
# 4:  2      1       0     15       2     3
# 5:  2      1      15    100       3     0
# 6:  2      1     100      0       0     0

如果您显示的输出确实是正确的并且是您需要的,那么您可以获得两条线(可能不是最好的方式,但它应该很快)

# remove rows where start.s and end.s are both 0
dt.out <- dt.out[, .SD[start.s > 0 | end.s > 0], by=1:nrow(dt.out)]
# replace end.s values with corresponding start.s values where end.s == 0
# it can be easily done with max(start.s, end.s) because end.s >= start.s ALWAYS
dt.out <- dt.out[, end.s := max(start.s, end.s), by=1:nrow(dt.out)]
dt.out[, nrow:=NULL]

> dt.out
#    id cohort t.start t.stop start.s end.s
# 1:  1      2       0     50       1     2
# 2:  1      2      50     70       2     4
# 3:  1      2      70    100       4     4
# 4:  2      1       0     15       2     3
# 5:  2      1      15    100       3     3