r:先前观察的总和值

时间:2016-04-15 20:28:04

标签: r sum

我想对每个ID的每两个先前观察值求和,并将它们放在一个名为' prior_work'的新列中。可能听起来很奇怪,但这里有一个例子,应该澄清我试图做的事情。我的数据框:

ID  Week  Hours
1   1     .00
1   2   24.00
1   3   25.00
1   4   22.00
1   5   19.00
1   6   20.00
2   1     .00
2   2     .00
2   3     .00
2   4     .00
2   5   16.00
2   6   16.00

我需要什么:

ID  Week  Hours  Hours_prior_two_weeks
1   1     .00    NA 
1   2   24.00    NA
1   3   25.00    24.00
1   4   22.00    49.00
1   5   19.00    47.00
1   6   20.00    41.00
2   1     .00    NA       #new ID / person here
2   2     .00    NA
2   3     .00      .00
2   4     .00      .00
2   5   16.00      .00
2   6   16.00    16.00

尝试了基本的聚合等等,但我无法弄清楚如何总结先前的观察结果'。谢谢!

3 个答案:

答案 0 :(得分:4)

library(dplyr)
df = data.frame(ID=rep(1:2, each=6), 
                Week=rep(1:6, each=2), 
                Hours=c(0,24,25,22,19,20,0,0,0,0,16,16))
df
#    ID Week Hours
# 1   1    1     0
# 2   1    1    24
# 3   1    2    25
# 4   1    2    22
# 5   1    3    19
# 6   1    3    20
# 7   2    4     0
# 8   2    4     0
# 9   2    5     0
# 10  2    5     0
# 11  2    6    16
# 12  2    6    16

df %>% group_by(ID) %>% mutate(Hours_Prior_Two_Weeks = lag(Hours, 2) + lag(Hours, 1))

# Source: local data frame [12 x 4]
# Groups: ID [2]
# 
#       ID  Week Hours Hours_Prior_Two_Weeks
#    (int) (int) (dbl)                 (dbl)
# 1      1     1     0                    NA
# 2      1     1    24                    NA
# 3      1     2    25                    24
# 4      1     2    22                    49
# 5      1     3    19                    47
# 6      1     3    20                    41
# 7      2     4     0                    NA
# 8      2     4     0                    NA
# 9      2     5     0                     0
# 10     2     5     0                     0
# 11     2     6    16                     0
# 12     2     6    16                    16

上述代码使用dplyrID变量进行分组,然后使用lag回顾最后两个值。

答案 1 :(得分:3)

您可以将ave功能与rollsum一起使用,需要更改fillalign参数的默认值才能获得您申请的结构:

> dat$Hours_prior_two_weeks <- with(dat, ave( Hours, ID, FUN=function(x) rollsum(x, k=3, fill=NA, align="right")))
> dat
   ID Week Hours Hours_prior_two_weeks
1   1    1     0                    NA
2   1    2    24                    NA
3   1    3    25                    49
4   1    4    22                    71
5   1    5    19                    66
6   1    6    20                    61
7   2    1     0                    NA
8   2    2     0                    NA
9   2    3     0                     0
10  2    4     0                     0
11  2    5    16                    16
12  2    6    16                    32

但是这并没有改变它们所以你需要在组内向量的开头添加一个额外的NA,并且在结尾之外留下一个NA(也在组内):

dat$Hours_prior_two_weeks <- with(dat, ave( Hours, ID, 
    FUN=function(x) c(NA, head(rollsum(x, k=2, fill=NA, align="right"), -1))) )
dat
#-----------
   ID Week Hours Hours_prior_two_weeks
1   1    1     0                    NA
2   1    2    24                    NA
3   1    3    25                    24
4   1    4    22                    49
5   1    5    19                    47
6   1    6    20                    41
7   2    1     0                    NA
8   2    2     0                    NA
9   2    3     0                     0
10  2    4     0                     0
11  2    5    16                     0
12  2    6    16                    16

答案 2 :(得分:3)

使用data.table

的选项
library(data.table)
setDT(df1)[,  Hours_prior_two_weeks := Reduce(`+`, shift(Hours, 1:2)), by = ID]
df1
#    ID Week Hours Hours_prior_two_weeks
# 1:  1    1     0                    NA
# 2:  1    2    24                    NA
# 3:  1    3    25                    24
# 4:  1    4    22                    49
# 5:  1    5    19                    47
# 6:  1    6    20                    41
# 7:  2    1     0                    NA
# 8:  2    2     0                    NA
# 9:  2    3     0                     0
#10:  2    4     0                     0
#11:  2    5    16                     0
#12:  2    6    16                    16