对 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' 的 lag
和 unnest
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写成w
。 ave
然后使用每个 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))
我有一个 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' 的 lag
和 unnest
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写成w
。 ave
然后使用每个 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))