Вот функция, которая должна быть относительно быстрой (вам нужно будет импортировать data.table
, чтобы она работала):
calculate_rolling_sum <- function(df, date_col, calc_col, id_var, k) {
return(setDT(df)[order(get(date_col)),][, paste(calc_col, "roll_sum", k, sep = "_") := sapply(get(date_col), function(x) sum(get(calc_col)[between(get(date_col), x - k, x)])),
by = mget(id_var)])
}
Пример кадра данных:
df <- data.frame(
state_A = c(rep("x", 6), rep("y", 4), rep("z", 6)),
state_B = c(rep("d", 16)),
imports_AB = c(rep(3, 3), rep(4, 4), rep(5, 2), rep(6, 2), rep(9, 3), rep(3, 2)),
yr = c(seq(2000, 2006, 1), seq(2009, 2017, 1))
)
state_A state_B imports_AB yr
1: x d 3 2000
2: x d 3 2001
3: x d 3 2002
4: x d 4 2003
5: x d 4 2004
6: x d 4 2005
7: y d 4 2006
8: y d 5 2009
9: y d 5 2010
10: y d 6 2011
11: z d 6 2012
12: z d 9 2013
13: z d 9 2014
14: z d 9 2015
15: z d 3 2016
16: z d 3 2017
Применение функции для текущего и последних 3 лет и нового кадра данных:
library(data.table)
df_rolling <- calculate_rolling_sum(df, date_col = "yr", calc_col = "imports_AB", id_var = c("state_A", "state_B"), k = 3)
df_rolling[]
state_A state_B imports_AB yr imports_AB_roll_sum_3
1: x d 3 2000 3
2: x d 3 2001 6
3: x d 3 2002 9
4: x d 4 2003 13
5: x d 4 2004 14
6: x d 4 2005 15
7: y d 4 2006 4
8: y d 5 2009 9
9: y d 5 2010 10
10: y d 6 2011 16
11: z d 6 2012 6
12: z d 9 2013 15
13: z d 9 2014 24
14: z d 9 2015 33
15: z d 3 2016 30
16: z d 3 2017 24
В чем преимущество этой функции перед стандартными функциями прокатки? Например, в 2010 году он больше не будет учитывать 2006 год, поскольку это не является обязательным требованием.
Обычные функции прокрутки, которые рассчитывают только по индексам строк, будут считать его (так как это на 2 строки ниже).
Таким образом, вам не нужно заботиться о том, есть ли у вас разрыв между годами, и нет необходимости заполнять набор данных.