对 window 的列值求和并报告前一个 window 的值

Sum column values over a window and report the values of the previous window

我有一个 data.frame 以下形式:

ID  Var1   
1    1 
1    1
1    3
1    4
1    1
1    0
2    2
2    2
2    6
2    7
2    8
2    0
3    0
3    2
3    1
3    3
3    2
3    4

我想到达那里:

ID  Var1  X  
1    1    0
1    1    0
1    3    0
1    4    5
1    1    5
1    0    5
2    2    0 
2    2    0
2    6    0
2    7    10
2    8    10
2    0    10
3    0    0
3    2    0
3    1    0
3    3    3
3    2    3
3    4    3

所以话说:我想计算一个window = 3中变量的总和,然后报告前面window中得到的结果。这应该发生在 ID 上,因此每个 ID 的前三个观察值应该返回 0,因为没有可以报告的先前时间段。 为了便于理解:在实际数据集中,每一行对应一周和 window = 7。所以 X 应该给出前一周 Var1 总和的信息。

我试过使用一些 rollapply 的东西,但总是以错误结束,而且 window 会滚动 window 如果我做对了,这特别不是我需要的。

感谢您的回答!

我们可以按 'ID' 分组,使用 gl 创建一个 window 大小为 3 的新分组列,然后通过采用 [= 'Var1' 的 14=] 并将 'Var1' 放在 list 中,得到 'X' 的 lagunnest

library(dplyr) #1.0.0    
library(tidyr)    
df1 %>%
     # // grouping by ID
     group_by(ID) %>%
     # // create another group added with gl
     group_by(grp = as.integer(gl(n(), 3, n())), .add = TRUE) %>% 
     # // get the sum of Var1, while changing the Var1 in a list
     summarise(X = sum(Var1), Var1 = list(Var1)) %>%
     # // get the lag of X
     mutate(X = lag(X, default = 0)) %>% 
     # // unnest the list column
     unnest(c(Var1)) %>%
     select(names(df1), X)
# A tibble: 18 x 3
# Groups:   ID [3]
#      ID  Var1     X
#   <int> <int> <dbl>
# 1     1     1     0
# 2     1     1     0
# 3     1     3     0
# 4     1     4     5
# 5     1     1     5
# 6     1     0     5
# 7     2     2     0
# 8     2     2     0
# 9     2     6     0
#10     2     7    10
#11     2     8    10
#12     2     0    10
#13     3     0     0
#14     3     2     0
#15     3     1     0
#16     3     3     3
#17     3     2     3
#18     3     4     3

数据

df1 <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), Var1 = c(1L, 1L, 3L, 4L, 1L, 
0L, 2L, 2L, 6L, 7L, 8L, 0L, 0L, 2L, 1L, 3L, 2L, 4L)), class = "data.frame",
row.names = c(NA, 
-18L))

rollapply中,宽度参数可以是一个列表,它提供了要使用的偏移量。在这种情况下,我们希望将点 3、2 和 1 用于第一个点,将 4、3 和 2 用于第二点,5、4 和 3 用于第三点,然后循环使用。也就是说,对于 k = 3 的 window 宽度,我们需要以下偏移向量列表:

w <- list(-(3:1), -(4:2), -(5:3))

一般我们可以根据window宽度k写成wave 然后使用每个 ID 的宽度列表调用 rollapply

library(zoo)

k <- 3
w <- lapply(1:k, function(x) seq(to = -x, length = k))
transform(DF, X = ave(Var1, ID, FUN = function(x) rollapply(x, w, sum, fill = 0)))

给予:

   ID Var1  X
1   1    1  0
2   1    1  0
3   1    3  0
4   1    4  5
5   1    1  5
6   1    0  5
7   2    2  0
8   2    2  0
9   2    6  0
10  2    7 10
11  2    8 10
12  2    0 10
13  3    0  0
14  3    2  0
15  3    1  0
16  3    3  3
17  3    2  3
18  3    4  3

备注

可重现形式的输入DF是:

DF <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
  2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), Var1 = c(1L, 1L, 3L, 4L, 1L, 
  0L, 2L, 2L, 6L, 7L, 8L, 0L, 0L, 2L, 1L, 3L, 2L, 4L)), 
  class = "data.frame", row.names = c(NA, -18L))