Examples for 'data.table::roll'


Rolling functions

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'

[Package data.table version 1.14.2 Index]