Получить перекрывающиеся значения по группе без цикла for (zoo, data.table) - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть data.table с временными рядами, и я пытаюсь вычислить несколько агрегаций на перекрывающихся временных интервалах, например, в феврале я хотел бы получить среднее значение данных за январь и февраль, за март - февраль и март и т. д.

Мне удалось рассчитать это с помощью цикла for, но, поскольку мой data.table содержит более 300 000 строк и несколько переменных, мне было интересно, есть ли более эффективный / элегантный способ добиться этого. Я пытался использовать rollapply из пакета zoo различными способами, но не получил ожидаемого результата.

library(data.table)
library(zoo)

# sample data 
dt <- data.table(day = Sys.Date() - 100:1, var = 1:100)
dt[, month := month(day)]

# by 1 month is pretty obvious 
dt[, mean(var), by = month]
   month   V1
1:     7  1.5
2:     8 18.0
3:     9 48.5
4:    10 79.0
5:    11 97.5

# by 2 months - solution using for loop = expected result
for (m in unique(dt[, month])[-1]) {
    dt[month == m, res := mean(dt[month %in% c(m, m-1), var])]
}
dt[, unique(res), by = month]
   month V1
1:     7 NA
2:     8 17
3:     9 33
4:    10 64
5:    11 82

# one of the things I tried
dt[, res := NULL]
lw <- dt[, .N, by = month][, N]
lw <- as.list(lw[-1] + lw[-length(lw)])
dt[, rollapplyr(var, width = lw, mean, fill = NA), by = month]
...