Aliases: roll froll rolling sliding moving rollmean frollmean rollsum frollsum rollapply frollapply
Keywords: data
### ** Examples d = as.data.table(list(1:6/2, 3:8/4)) # rollmean of single vector and single window frollmean(d[, V1], 3)
[1] NA NA 1.0 1.5 2.0 2.5
# multiple columns at once frollmean(d, 3)
[[1]] [1] NA NA 1.0 1.5 2.0 2.5 [[2]] [1] NA NA 1.00 1.25 1.50 1.75
# multiple windows at once frollmean(d[, .(V1)], c(3, 4))
[[1]] [1] NA NA 1.0 1.5 2.0 2.5 [[2]] [1] NA NA NA 1.25 1.75 2.25
# multiple columns and multiple windows at once frollmean(d, c(3, 4))
[[1]] [1] NA NA 1.0 1.5 2.0 2.5 [[2]] [1] NA NA NA 1.25 1.75 2.25 [[3]] [1] NA NA 1.00 1.25 1.50 1.75 [[4]] [1] NA NA NA 1.125 1.375 1.625
## three calls above will use multiple cores when available # partial window using adaptive rolling function an = function(n, len) c(seq.int(n), rep(n, len-n)) n = an(3, nrow(d)) frollmean(d, n, adaptive=TRUE)
[[1]] [1] 0.50 0.75 1.00 1.50 2.00 2.50 [[2]] [1] 0.750 0.875 1.000 1.250 1.500 1.750
# frollsum frollsum(d, 3:4)
[[1]] [1] NA NA 3.0 4.5 6.0 7.5 [[2]] [1] NA NA NA 5 7 9 [[3]] [1] NA NA 3.00 3.75 4.50 5.25 [[4]] [1] NA NA NA 4.5 5.5 6.5
# frollapply frollapply(d, 3:4, sum)
[[1]] [1] NA NA 3.0 4.5 6.0 7.5 [[2]] [1] NA NA NA 5 7 9 [[3]] [1] NA NA 3.00 3.75 4.50 5.25 [[4]] [1] NA NA NA 4.5 5.5 6.5
f = function(x, ...) if (sum(x, ...)>5) min(x, ...) else max(x, ...) frollapply(d, 3:4, f, na.rm=TRUE)
[[1]] [1] NA NA 1.5 2.0 1.5 2.0 [[2]] [1] NA NA NA 2.0 1.0 1.5 [[3]] [1] NA NA 1.25 1.50 1.75 1.50 [[4]] [1] NA NA NA 1.50 1.00 1.25
# performance vs exactness set.seed(108) x = sample(c(rnorm(1e3, 1e6, 5e5), 5e9, 5e-9)) n = 15 ma = function(x, n, na.rm=FALSE) { ans = rep(NA_real_, nx<-length(x)) for (i in n:nx) ans[i] = mean(x[(i-n+1):i], na.rm=na.rm) ans } fastma = function(x, n, na.rm) { if (!missing(na.rm)) stop("NAs are unsupported, wrongly propagated by cumsum") cs = cumsum(x) scs = shift(cs, n) scs[n] = 0 as.double((cs-scs)/n) } system.time(ans1<-ma(x, n))
user system elapsed 0.004000000 0.000000000 0.008000001
system.time(ans2<-fastma(x, n))
user system elapsed 0.001 0.000 0.000
system.time(ans3<-frollmean(x, n))
user system elapsed 0 0 0
system.time(ans4<-frollmean(x, n, algo="exact"))
user system elapsed 0 0 0
system.time(ans5<-frollapply(x, n, mean))
user system elapsed 0.003000000 0.000000000 0.002999999
anserr = list( fastma = ans2-ans1, froll_fast = ans3-ans1, froll_exact = ans4-ans1, frollapply = ans5-ans1 ) errs = sapply(lapply(anserr, abs), sum, na.rm=TRUE) sapply(errs, format, scientific=FALSE) # roundoff
fastma froll_fast froll_exact frollapply "0.00001287466" "0.00000001833541" "0" "0"
# frollapply corner cases f = function(x) head(x, 2) ## FUN returns non length 1 try(frollapply(1:5, 3, f))
Error in frollapply(1:5, 3, f) : frollapply: results from provided FUN are not length 1
f = function(x) { ## FUN sometimes returns non length 1 n = length(x) # length 1 will be returned only for first iteration where we check length if (n==x[n]) x[1L] else range(x) # range(x)[2L] is silently ignored! } frollapply(1:5, 3, f)
[1] NA NA 1 2 3
options(datatable.verbose=TRUE) x = c(1,2,1,1,1,2,3,2) frollapply(x, 3, uniqueN) ## FUN returns integer
frollapplyR: allocating memory for results 1x1 forder.c received 3 rows and 1 columns frollapply: results from provided FUN are not of type double, coercion from integer or logical will be applied on each iteration forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns frollapply: took 0.000s frollapplyR: processing of 1 column(s) and 1 window(s) took 0.000s
[1] NA NA 2 2 1 2 3 2
numUniqueN = function(x) as.numeric(uniqueN(x)) frollapply(x, 3, numUniqueN)
frollapplyR: allocating memory for results 1x1 forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns forder.c received 3 rows and 1 columns frollapply: took 0.000s frollapplyR: processing of 1 column(s) and 1 window(s) took 0.000s
[1] NA NA 2 2 1 2 3 2
x = c(1,2,1,1,NA,2,NA,2) frollapply(x, 3, anyNA) ## FUN returns logical
frollapplyR: allocating memory for results 1x1 frollapply: results from provided FUN are not of type double, coercion from integer or logical will be applied on each iteration frollapply: took 0.000s frollapplyR: processing of 1 column(s) and 1 window(s) took 0.000s
[1] NA NA 0 0 1 1 1 1
as.logical(frollapply(x, 3, anyNA))
frollapplyR: allocating memory for results 1x1 frollapply: results from provided FUN are not of type double, coercion from integer or logical will be applied on each iteration frollapply: took 0.000s frollapplyR: processing of 1 column(s) and 1 window(s) took 0.000s
[1] NA NA FALSE FALSE TRUE TRUE TRUE TRUE
options(datatable.verbose=FALSE) f = function(x) { ## FUN returns character if (sum(x)>5) "big" else "small" } try(frollapply(1:5, 3, f))
Error in frollapply(1:5, 3, f) : frollapply: results from provided FUN are not of type double
f = function(x) { ## FUN is not type-stable n = length(x) # double type will be returned only for first iteration where we check type if (n==x[n]) 1 else NA # NA logical turns into garbage without coercion to double } try(frollapply(1:5, 3, f))
Error in frollapply(1:5, 3, f) : REAL() can only be applied to a 'numeric', not a 'logical'