частичная скользящая сумма в data.table в r - PullRequest
2 голосов
/ 30 марта 2020

Я ищу быстрый способ реализации скользящей суммы в большой базе данных. Мне нужна быстрая функция, которая поддерживает как левое (и правое) выравнивание, так и аргумент для минимального наблюдения.

По сути, я хочу вычислить скользящую сумму, даже если размер выборки меньше указанной ширины. В приведенном ниже примере я хочу получить сумму следующих 5 значений, когда доступны следующие 5 значений, а если размер начальных значений меньше 5, то суммируем переброс всех оставшихся значений.

Пример : x <- seq(1:10)

Желаемый вывод:

15 20 25 30 35 40 34 27 19 10

Я знаю, что rollapply(x,5, sum, align = "left", partial=1) обеспечивает требуемый вывод, но ищу более быстрое решение.

frollsum из пакета data.table работает быстро, но, похоже, не имеет аргумента для минимального наблюдения. roll_sum из рулона пакетов также быстр и принимает значение для минимального наблюдения, но не поддерживает выравнивание по левому краю.

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 30 марта 2020

Начиная с data.table_1.12.8, frollsum не поддерживает align="left" с adaptive=TRUE, однако вы можете настроить его следующим образом, используя rev:

library(data.table) #data.table_1.12.8

lrfrollsum <- function(x, k, align) {
    nk <- c(seq.int(k), rep(k, length(x) - k))
    switch(align, 
        left={ 
            rev(frollsum(rev(x), nk, align="right", adaptive=TRUE))
        },
        right={
            frollsum(x, nk, align="right", adaptive=TRUE)   
        })
}

x <- 1:10

lrfrollsum(x, 5, align="left")
# [1] 15 20 25 30 35 40 34 27 19 10

lrfrollsum(x, 5, align="right")
# [1]  1  3  6 10 15 20 25 30 35 40

Надеюсь, это достаточно быстро .

0 голосов
/ 30 марта 2020

Я не думал об использовании rev! Вдохновленный вашим ответом, еще одно возможное решение:

library(roll)
x <- seq(1:10)
rev(roll_sum(rev(x),5,min_obs = 1))
# [1] 15 20 25 30 35 40 34 27 19 10

Спасибо!

...