【问题标题】:cumulative variable construction in longitudinal data set纵向数据集中的累积变量构造
【发布时间】:2013-12-21 22:26:41
【问题描述】:

问题: 我想构建一个变量来衡量人年纵向数据集中的累积工作经验。该问题适用于各种纵向数据集,并且许多变量可能以这种累积方式构建(例如,孩子的数量、累积教育、累积的假期花费等)

案例: 我有一个大型纵向数据集,其中每一行构成一个人年。该数据集包含数千人(变量“ID”)在他们的生活中跟随(变量“年龄”),产生了一个包含大约 120 万行的数据框。一个变量表示一个人每年工作了多少个月(变量“工作”)。例如,丹 15 岁时工作了 3 个月。

     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 万行,循环遍历每一行效率非常低,运行此循环需要数小时。是否有任何出色的程序员对如何最有效地构建这种累积度量提出建议?

提前非常感谢!

最好, 拉斐尔

【问题讨论】:

    标签: r


    【解决方案1】:

    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
    

    但是,鉴于您的数据规模,我还强烈建议您使用“data.table”包,它还可以让您访问方便的语法:

    library(data.table)
    DT <- data.table(x)
    DT[, cumwork := cumsum(work), by = ID]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      相关资源
      最近更新 更多