R 纵向数据集中的累积变量构造
问题: 我想构建一个变量来衡量一个人-年纵向数据集中的累积工作经验。这个问题适用于所有类型的纵向数据集,许多变量可能是以这种累积方式构建的(例如,孩子数量、累积教育、度假累计花费等) 案例: 我有一个大型纵向数据集,其中每一行构成一个人年。该数据集包含数千人(变量“ID”)的一生(变量“年龄”),形成了一个约120万行的数据框架。一个变量表示一个人每年工作的月数(变量“工作”)。例如,当丹15岁时,他工作了3个月R 纵向数据集中的累积变量构造,r,R,问题: 我想构建一个变量来衡量一个人-年纵向数据集中的累积工作经验。这个问题适用于所有类型的纵向数据集,许多变量可能是以这种累积方式构建的(例如,孩子数量、累积教育、度假累计花费等) 案例: 我有一个大型纵向数据集,其中每一行构成一个人年。该数据集包含数千人(变量“ID”)的一生(变量“年龄”),形成了一个约120万行的数据框架。一个变量表示一个人每年工作的月数(变量“工作”)。例如,当丹15岁时,他工作了3个月 ID age work 1 Dan 10 0 2 Dan
ID age work
1 Dan 10 0
2 Dan 11 0
3 Dan 12 0
4 Dan 13 0
5 Dan 14 0
6 Dan 15 3
7 Dan 16 5
8 Dan 17 8
9 Dan 18 5
10 Dan 19 12
11 Jeff 20 0
12 Jeff 16 0
13 Jeff 17 0
14 Jeff 18 0
15 Jeff 19 0
16 Jeff 20 0
17 Jeff 21 8
18 Jeff 22 10
19 Jeff 23 12
20 Jeff 24 12
21 Jeff 25 12
22 Jeff 26 12
23 Jeff 27 12
24 Jeff 28 12
25 Jeff 29 12
我现在想构造一个累积工作经验变量,它将x年的值与x+1年的值相加。目标是了解每个年龄段的人在整个航空公司工作了多少个月。变量应该看起来像“cumwork”
ID age work cumwork
1 Dan 10 0 0
2 Dan 11 0 0
3 Dan 12 0 0
4 Dan 13 0 0
5 Dan 14 0 0
6 Dan 15 3 3
7 Dan 16 5 8
8 Dan 17 8 16
9 Dan 18 5 21
10 Dan 19 12 33
11 Jeff 20 0 0
12 Jeff 16 0 0
13 Jeff 17 0 0
14 Jeff 18 0 0
15 Jeff 19 0 0
16 Jeff 20 0 0
17 Jeff 21 8 8
18 Jeff 22 10 18
19 Jeff 23 12 30
20 Jeff 24 12 42
21 Jeff 25 12 54
22 Jeff 26 12 66
23 Jeff 27 12 78
24 Jeff 28 12 90
25 Jeff 29 12 102
糟糕的解决方案:我可以使用以下简单循环构造这样一个累积变量:
# Generate test data set
x=data.frame(ID=c(rep("Dan",times=10),rep("Jeff",times=15)),age=c(10:20,16:29),work=c(rep(0,times=5),3,5,8,5,12,rep(0,times=6),8,10,rep(12,times=7)),stringsAsFactors=F)
# Generate cumulative work experience variable
x$cumwork=x$work
for(r in 2:nrow(x)){
if(x$ID[r]==x$ID[r-1]){
x$cumwork[r]=x$cumwork[r-1]+x$cumwork[r]
}
}
然而,我的数据集有120万行,每行循环效率很低,运行这个循环需要几个小时。有没有聪明的程序员对如何最有效地构建这个累积度量有什么建议
非常感谢
最好的,
拉斐尔
ave
对这些类型的任务很方便。要与之配合使用的函数是cumsum
:
x$cumwork <- ave(x$work, x$ID, FUN = cumsum)
x
# ID age work cumwork
# 1 Dan 10 0 0
# 2 Dan 11 0 0
# 3 Dan 12 0 0
# 4 Dan 13 0 0
# 5 Dan 14 0 0
# 6 Dan 15 3 3
# 7 Dan 16 5 8
# 8 Dan 17 8 16
# 9 Dan 18 5 21
# 10 Dan 19 12 33
# 11 Jeff 20 0 0
# 12 Jeff 16 0 0
# 13 Jeff 17 0 0
# 14 Jeff 18 0 0
# 15 Jeff 19 0 0
# 16 Jeff 20 0 0
# 17 Jeff 21 8 8
# 18 Jeff 22 10 18
# 19 Jeff 23 12 30
# 20 Jeff 24 12 42
# 21 Jeff 25 12 54
# 22 Jeff 26 12 66
# 23 Jeff 27 12 78
# 24 Jeff 28 12 90
# 25 Jeff 29 12 102
x$cumwork
library(data.table)
DT <- data.table(x)
DT[, cumwork := cumsum(work), by = ID]