寻找一种方法来填充具有新值的向量,条件是该向量中的值和数据框中的另一个变量。粘贴下面数据的示例。
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
表示某人在该人日结束。之后的人日表示新剧集。
我想使用OutVar
和PrsVar
中的值创建一个看起来像IndVar
的变量。这个新变量OutVar
标记每个人日所在的剧集,增加1,并为每个新个人重新开始。
我可以通过循环运行它,但我需要更高效的代码来处理3,000,000多行数据。试图使用dplyr
或mapply
中的内容,但我很难过。考虑解决这个问题对其他人有帮助,在不久的将来肯定会对我有所帮助。
答案 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