I am looking for a fast way to implement a rolling sum on a big database. What I want is a fast function that supports both left (and right) alignment and an arguement for min observation.
Essentially, I want to calculate the rolling sum even if the sample size is smaller than the specified width. In the example below, I want the sum of next 5 values whenever next 5 values are available, and if the size of the leading values is smaller than 5, then summing the roll over all that is left.
Example: x <- seq(1:10)
Desired output:
15 20 25 30 35 40 34 27 19 10
I know that rollapply(x,5, sum, align = "left", partial=1)
procudes the desired output, but am looking for a faster solution.
frollsum
from the package data.table is fast but does not seem to have an arguement for min observation. roll_sum
from the package roll is also fast and accepts a value for min observation, but does not support left alignment.
Thanks in advance.
As of data.table_1.12.8
, frollsum
does not support align="left"
with adaptive=TRUE
, however you can tweak it as follows using 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
Hopefully, this is fast enough.
I hadn't thought about using rev
! Inspired by @chinsoon12 answer, another possible solution is
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
Thanks!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.