条件系列填写R

时间:2016-01-18 04:15:34

标签: r time-series

寻找一种方法来填充具有新值的向量,条件是该向量中的值和数据框中的另一个变量。粘贴下面数据的示例。

PrsVar= c(rep(1,10),rep(2,7),rep(3,11))
IndVar = c(0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0)
OutVar = c(1,1,1,1,2,2,2,3,3,3,1,1,1,1,2,2,2,1,1,1,1,2,2,2,2,3,3,3)
exampdata <- cbind(PrsVar,IndVar,OutVar)
exampdata <- as.data.frame(exampdata)

> exampdata
   PrsVar IndVar OutVar
1       1      0      1
2       1      0      1
3       1      0      1
4       1      1      1
5       1      0      2
6       1      0      2
7       1      1      2
8       1      0      3
9       1      0      3
10      1      0      3
11      2      0      1
12      2      0      1
13      2      0      1
14      2      1      1
15      2      0      2
16      2      0      2
17      2      1      2
18      3      0      1
19      3      0      1
20      3      0      1
21      3      1      1
22      3      0      2
23      3      0      2
24      3      0      2
25      3      1      2
26      3      0      3
27      3      0      3
28      3      0      3

这是时间序列数据,每行代表一个人日。 PrsVar是研究中个人的ID,IndVar表示某人在该人日结束。之后的人日表示新剧集。

我想使用OutVarPrsVar中的值创建一个看起来像IndVar的变量。这个新变量OutVar标记每个人日所在的剧集,增加1,并为每个新个人重新开始。

我可以通过循环运行它,但我需要更高效的代码来处理3,000,000多行数据。试图使用dplyrmapply中的内容,但我很难过。考虑解决这个问题对其他人有帮助,在不久的将来肯定会对我有所帮助。

2 个答案:

答案 0 :(得分:3)

data.table包提供了一种快速,高效且整洁的方法。这一切都是通过引用完成的(不是通过值,因此不进行复制),因此数百万行根本不会成为问题(可能在一分钟之内)。

library(data.table)
patient.data <- data.table(PrsVar = c(rep(1,10), rep(2,7), rep(3,11)),
                           IndVar = c(0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0),
                           OutVar = c(1,1,1,1,2,2,2,3,3,3,1,1,1,1,2,2,2,1,1,1,1,2,2,2,2,3,3,3))

根据EpVar(加IndVar)的累积总和增加一集的计数器1。这会增加IndVar增加的记录(这太早)的计数器,因此将其向下移动到shift的记录,用重置计数器(1)替换缺失的值。这可以使用by关键字分组完成。

patient.data[ , EpVar:=shift(1+cumsum(IndVar), fill=1), by=PrsVar]
patient.data
    PrsVar IndVar OutVar EpVar
 1:      1      0      1     1
 2:      1      0      1     1
 3:      1      0      1     1
 4:      1      1      1     1
 5:      1      0      2     2
 6:      1      0      2     2
 7:      1      1      2     2
 8:      1      0      3     3
 9:      1      0      3     3
10:      1      0      3     3
11:      2      0      1     1
12:      2      0      1     1
13:      2      0      1     1
14:      2      1      1     1
15:      2      0      2     2
16:      2      0      2     2
17:      2      1      2     2
18:      3      0      1     1
19:      3      0      1     1
20:      3      0      1     1
21:      3      1      1     1
22:      3      0      2     2
23:      3      0      2     2
24:      3      0      2     2
25:      3      1      2     2
26:      3      0      3     3
27:      3      0      3     3
28:      3      0      3     3

答案 1 :(得分:1)

有点难看,但这个逻辑应该很容易适应其他方法:

with(exampdata,
  ave(IndVar, PrsVar, FUN=function(x) {
    out <- rev(cumsum(rev(x)))
    max(out) - out + 1
  })
)

# [1] 1 1 1 1 2 2 2 3 3 3 1 1 1 1 2 2 2 1 1 1 1 2 2 2 2 3 3 3