Skip to content

Commit 4b05edd

Browse files
authored
froll supports window of size 0 (#7286)
1 parent 0687c40 commit 4b05edd

File tree

8 files changed

+198
-39
lines changed

8 files changed

+198
-39
lines changed

R/frollapply.R

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,11 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
209209
cpy = copy
210210
ansMask = function(len, n) {
211211
mask = rep(TRUE, len)
212-
mask[seq_len(n-1L)] = FALSE
212+
if (n) ## handle n==0
213+
mask[seq_len(n-1L)] = FALSE
213214
mask
214215
}
216+
tight0 = function(i, dest, src, n) FUN(dest, ...) ## skip memcpy when n==0
215217
if (by.column) {
216218
allocWindow = function(x, n) x[seq_len(n)]
217219
tight = function(i, dest, src, n) FUN(.Call(CmemcpyVector, dest, src, i, n), ...)
@@ -237,9 +239,9 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
237239
if (by.column) {
238240
allocWindow = function(x, n) x[seq_len(max(n, na.rm=TRUE))]
239241
if (has.growable) {
240-
tight = function(i, dest, src, n) FUN(.Call(CmemcpyVectoradaptive, dest, src, i, n), ...)
242+
tight = function(i, dest, src, n) FUN(.Call(CmemcpyVectoradaptive, dest, src, i, n), ...) # CmemcpyVectoradaptive handles k[i]==0
241243
} else {
242-
tight = function(i, dest, src, n) FUN(src[(i-n[i]+1L):i], ...) # nocov
244+
tight = function(i, dest, src, n) {stopf("internal error: has.growable should be TRUE, implement support for n==0"); FUN(src[(i-n[i]+1L):i], ...)} # nocov
243245
}
244246
} else {
245247
if (!list.df) {
@@ -248,12 +250,12 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
248250
allocWindow = function(x, n) lapply(x, `[`, seq_len(max(n)))
249251
}
250252
if (has.growable) {
251-
tight = function(i, dest, src, n) FUN(.Call(CmemcpyDTadaptive, dest, src, i, n), ...)
253+
tight = function(i, dest, src, n) FUN(.Call(CmemcpyDTadaptive, dest, src, i, n), ...) # CmemcpyDTadaptive handles k[i]==0
252254
} else {
253255
if (!list.df) { # nocov
254-
tight = function(i, dest, src, n) FUN(src[(i-n[i]+1L):i, , drop=FALSE], ...) # nocov
256+
tight = function(i, dest, src, n) {stopf("internal error: has.growable should be TRUE, implement support for n==0"); FUN(src[(i-n[i]+1L):i, , drop=FALSE], ...)} # nocov
255257
} else {
256-
tight = function(i, dest, src, n) FUN(lapply(src, `[`, (i-n[i]+1L):i), ...) # nocov
258+
tight = function(i, dest, src, n) {stopf("internal error: has.growable should be TRUE, implement support for n==0"); FUN(lapply(src, `[`, (i-n[i]+1L):i), ...)} # nocov
257259
}
258260
}
259261
}
@@ -288,6 +290,11 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
288290
w = allocWindow(thisx, thisn) ## prepare window, handles adaptive
289291
ansmask = ansMask(thislen, thisn)
290292
ansi = which(ansmask)
293+
tightFUN = if (adaptive || thisn) { ## handle n==0 for !adaptive, for !adaptive thisn should be scalar
294+
tight
295+
} else {
296+
tight0
297+
}
291298
if (use.fork) { ## !windows && getDTthreads()>1L
292299
ths = min(DTths, length(ansi))
293300
ii = split(ansi, sort(rep_len(seq_len(ths), length(ansi)))) ## assign row indexes to threads
@@ -298,7 +305,7 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
298305
# nocov start ## fork processes seem not to be tracked by codecov, at least when parallel not in suggests
299306
setDTthreads(1L) ## disable nested parallelism
300307
lapply(ii[[th]], ## loops over indexes for that thread
301-
FUN = tight, ## handles adaptive and by.column
308+
FUN = tightFUN, ## handles adaptive and by.column
302309
dest = cpy(w), ## allocate own window for each thread, if we would not copy here, then copy would be handled later on by fork's copy-on-write
303310
src = thisx, ## full input
304311
n = thisn) ## scalar or in adaptive case a vector
@@ -341,7 +348,7 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
341348
oldDTthreads = setDTthreads(1L) ## for consistency, anyway window size is unlikely to be big enough to benefit any parallelism
342349
withCallingHandlers(
343350
tryCatch(
344-
thisans <- lapply(ansi, FUN = tight, dest = cpy(w), src = thisx, n = thisn),
351+
thisans <- lapply(ansi, FUN = tightFUN, dest = cpy(w), src = thisx, n = thisn),
345352
error = function(e) h$err = conditionMessage(e)
346353
), warning = function(w) {
347354
#h$warn = c(h$warn, conditionMessage(w)) ## warnings are suppressed for consistency to parallel processing code

inst/tests/froll.Rraw

Lines changed: 112 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ test(6000.019, frollmean(x, TRUE), error="n must be integer")
9494
test(6000.020, frollmean(x, list(1:10)), error="n must be integer, list is accepted for adaptive TRUE")
9595
test(6000.021, frollmean(x, list(NA), adaptive=TRUE), error="n must be an integer vector or list of an integer vectors")
9696
test(6000.022, frollmean(x, list(c(1:5,1:5), NA), adaptive=TRUE), error="n must be an integer vector or list of an integer vectors")
97-
test(6000.0221, frollmean(1:2, list(c(0L, 0L)), adaptive=TRUE), error="n must be positive integer values")
9897

9998
#### various length list vectors
10099
l = list(1:6/2, 3:10/4)
@@ -369,13 +368,13 @@ test(6000.084, frollmean(list(1:3, numeric()), 2), list(c(NA_real_, 1.5, 2.5), n
369368
#### length(n)==0
370369
test(6000.085, frollmean(1:3, integer()), error="n must be non 0 length")
371370
test(6000.086, frollmean(list(1:3, 2:4), integer()), error="n must be non 0 length")
372-
#### n==0
373-
test(6000.087, frollmean(1:3, c(2,0)), error="n must be positive integer values")
374-
test(6000.088, frollmean(list(1:3, 2:4), 0), error="n must be positive integer values")
371+
#### n==0 (k==0, k[i]==0)
372+
## 6000.87 6000.88 moved to 6001.
375373
#### n<0
376-
test(6000.089, frollmean(1:3, -2), error="n must be positive integer values")
374+
test(6000.089, frollmean(1:3, -2), error="n must be non-negative integer values")
375+
test(6000.0891, frollmean(1:3, c(-2,2), adaptive=TRUE), error="n must be non-negative integer values")
377376
#### n[[1L]]>0 && n[[2L]]<0
378-
test(6000.090, frollmean(1:3, c(2, -2)), error="n must be positive integer values")
377+
test(6000.090, frollmean(1:3, c(2, -2)), error="n must be non-negative integer values")
379378
#### n[[1L]]==n[[2L]]
380379
test(6000.091, frollmean(1:3, c(2, 2)), list(c(NA_real_, 1.5, 2.5), c(NA_real_, 1.5, 2.5)))
381380
test(6000.092, frollmean(list(1:3, 4:6), c(2, 2)), list(c(NA_real_, 1.5, 2.5), c(NA_real_, 1.5, 2.5), c(NA_real_, 4.5, 5.5), c(NA_real_, 4.5, 5.5)))
@@ -412,9 +411,9 @@ test(6000.111, frollmean(list(1, 10, 5), 2, align="left"), list(NA_real_, NA_rea
412411
test(6000.112, frollmean(5, 2, align="center"), NA_real_)
413412
test(6000.113, frollmean(list(1, 10, 5), 2, align="center"), list(NA_real_, NA_real_, NA_real_))
414413
#### n==Inf
415-
test(6000.114, frollmean(1:5, Inf), error="n must be positive integer values", warning="NAs introduced by coercion*")
414+
test(6000.114, frollmean(1:5, Inf), error="n must be non-negative integer values", warning="NAs introduced by coercion*")
416415
#### n==c(5, Inf)
417-
test(6000.115, frollmean(1:5, c(5, Inf)), error="n must be positive integer values", warning="NAs introduced by coercion*")
416+
test(6000.115, frollmean(1:5, c(5, Inf)), error="n must be non-negative integer values", warning="NAs introduced by coercion*")
418417
#### is.complex(n)
419418
test(6000.116, frollmean(1:5, 3i), error="n must be integer")
420419
#### is.character(n)
@@ -1006,6 +1005,91 @@ test(6000.502, frollmax(c(5,NaN,1), 1L), c(5,NaN,1))
10061005
test(6000.503, frollmax(c(5,1,1,NaN,1,1,1), 2L), c(NA,5,1,NaN,NaN,1,1))
10071006
test(6000.504, frollmax(c(5,1,NA,NaN,1,1,1), 2L), c(NA,5,NA,NA,NaN,1,1))
10081007

1008+
# n==0, k==0, k[i]==0
1009+
test(6001.111, frollmean(1:3, 0), c(NaN,NaN,NaN), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1010+
test(6001.112, frollmean(1:3, 0, fill=99), c(NaN,NaN,NaN))
1011+
test(6001.113, frollmean(c(1:2,NA), 0), c(NaN,NaN,NaN))
1012+
test(6001.114, frollmean(c(1:2,NA), 0, na.rm=TRUE), c(NaN,NaN,NaN))
1013+
test(6001.115, frollmean(1:3, 0, algo="exact"), c(NaN,NaN,NaN), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1014+
test(6001.116, frollmean(c(1:2,NA), 0, algo="exact"), c(NaN,NaN,NaN))
1015+
test(6001.117, frollmean(c(1:2,NA), 0, algo="exact", na.rm=TRUE), c(NaN,NaN,NaN))
1016+
test(6001.121, frollmean(adaptive=TRUE, 1:3, c(2,0,2)), c(NA,NaN,2.5))
1017+
test(6001.122, frollmean(adaptive=TRUE, 1:3, c(2,0,2), fill=99), c(99,NaN,2.5))
1018+
test(6001.123, frollmean(adaptive=TRUE, c(1:2,NA), c(2,0,2)), c(NA,NaN,NA))
1019+
test(6001.124, frollmean(adaptive=TRUE, c(1:2,NA), c(2,0,2), na.rm=TRUE), c(NA,NaN,2))
1020+
test(6001.125, frollmean(adaptive=TRUE, 1:3, c(2,0,2), algo="exact"), c(NA,NaN,2.5))
1021+
test(6001.126, frollmean(adaptive=TRUE, 1:3, c(2,0,2), fill=99, algo="exact"), c(99,NaN,2.5))
1022+
test(6001.127, frollmean(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact"), c(NA,NaN,NA))
1023+
test(6001.128, frollmean(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact", na.rm=TRUE), c(NA,NaN,2))
1024+
test(6001.129, frollmean(adaptive=TRUE, c(1:2,NA), c(2,0,2), fill=99, algo="exact", na.rm=TRUE), c(99,NaN,2))
1025+
test(6001.181, frollapply(FUN=mean, 1:3, 0), c(NaN,NaN,NaN))
1026+
test(6001.182, frollapply(FUN=mean, 1:3, 0, fill=99), c(NaN,NaN,NaN))
1027+
test(6001.183, frollapply(FUN=mean, c(1:2,NA), 0), c(NaN,NaN,NaN))
1028+
test(6001.184, frollapply(FUN=mean, c(1:2,NA), 0, na.rm=TRUE), c(NaN,NaN,NaN))
1029+
test(6001.1910, frollapply(FUN=mean, adaptive=TRUE, 1:3, c(2,0,2)), c(NA,NaN,2.5))
1030+
test(6001.1911, frollapply(FUN=mean, adaptive=TRUE, list(1:3,2:4), c(2,0,2)), list(c(NA, NaN, 2.5), c(NA, NaN, 3.5)))
1031+
test(6001.1912, frollapply(FUN=mean, adaptive=TRUE, 1:3, list(c(2,0,2), c(0,2,0))), list(c(NA,NaN,2.5), c(NaN,1.5,NaN)))
1032+
test(6001.1913, frollapply(FUN=mean, adaptive=TRUE, list(1:3,2:4), list(c(2,0,2), c(0,2,0))), list(c(NA,NaN,2.5), c(NaN,1.5,NaN), c(NA,NaN,3.5), c(NaN,2.5,NaN)))
1033+
test(6001.192, frollapply(FUN=mean, adaptive=TRUE, 1:3, c(2,0,2), fill=99), c(99,NaN,2.5))
1034+
test(6001.193, frollapply(FUN=mean, adaptive=TRUE, c(1:2,NA), c(2,0,2)), c(NA,NaN,NA))
1035+
test(6001.194, frollapply(FUN=mean, adaptive=TRUE, c(1:2,NA), c(2,0,2), na.rm=TRUE), c(NA,NaN,2))
1036+
1037+
test(6001.211, frollsum(1:3, 0), c(0,0,0), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1038+
test(6001.212, frollsum(1:3, 0, fill=99), c(0,0,0))
1039+
test(6001.213, frollsum(c(1:2,NA), 0), c(0,0,0))
1040+
test(6001.214, frollsum(c(1:2,NA), 0, na.rm=TRUE), c(0,0,0))
1041+
test(6001.215, frollsum(1:3, 0, algo="exact"), c(0,0,0), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1042+
test(6001.216, frollsum(c(1:2,NA), 0, algo="exact"), c(0,0,0))
1043+
test(6001.217, frollsum(c(1:2,NA), 0, algo="exact", na.rm=TRUE), c(0,0,0))
1044+
test(6001.221, frollsum(adaptive=TRUE, 1:3, c(2,0,2)), c(NA,0,5))
1045+
test(6001.222, frollsum(adaptive=TRUE, 1:3, c(2,0,2), fill=99), c(99,0,5))
1046+
test(6001.223, frollsum(adaptive=TRUE, c(1:2,NA), c(2,0,2)), c(NA,0,NA))
1047+
test(6001.224, frollsum(adaptive=TRUE, c(1:2,NA), c(2,0,2), na.rm=TRUE), c(NA,0,2))
1048+
test(6001.225, frollsum(adaptive=TRUE, 1:3, c(2,0,2), algo="exact"), c(NA,0,5))
1049+
test(6001.226, frollsum(adaptive=TRUE, 1:3, c(2,0,2), fill=99, algo="exact"), c(99,0,5))
1050+
test(6001.227, frollsum(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact"), c(NA,0,NA))
1051+
test(6001.228, frollsum(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact", na.rm=TRUE), c(NA,0,2))
1052+
test(6001.229, frollsum(adaptive=TRUE, c(1:2,NA), c(2,0,2), fill=99, algo="exact", na.rm=TRUE), c(99,0,2))
1053+
test(6001.281, frollapply(FUN=sum, as.numeric(1:3), 0), c(0,0,0))
1054+
test(6001.282, frollapply(FUN=sum, as.numeric(1:3), 0, fill=99), c(0,0,0))
1055+
test(6001.283, frollapply(FUN=sum, c(1:2,NA_real_), 0), c(0,0,0))
1056+
test(6001.284, frollapply(FUN=sum, c(1:2,NA_real_), 0, na.rm=TRUE), c(0,0,0))
1057+
test(6001.2910, frollapply(FUN=sum, adaptive=TRUE, as.numeric(1:3), c(2,0,2)), c(NA,0,5))
1058+
test(6001.2911, frollapply(FUN=sum, adaptive=TRUE, list(as.numeric(1:3), as.numeric(2:4)), c(2,0,2)), list(c(NA,0,5), c(NA,0,7)))
1059+
test(6001.2912, frollapply(FUN=sum, adaptive=TRUE, as.numeric(1:3), list(c(2,0,2), c(0,2,0))), list(c(NA,0,5), c(0,3,0)))
1060+
test(6001.2913, frollapply(FUN=sum, adaptive=TRUE, list(as.numeric(1:3), as.numeric(2:4)), list(c(2,0,2), c(0,2,0))), list(c(NA,0,5), c(0,3,0), c(NA,0,7), c(0,5,0)))
1061+
test(6001.292, frollapply(FUN=sum, adaptive=TRUE, as.numeric(1:3), c(2,0,2), fill=99), c(99,0,5))
1062+
test(6001.293, frollapply(FUN=sum, adaptive=TRUE, c(1:2,NA_real_), c(2,0,2)), c(NA,0,NA))
1063+
test(6001.294, frollapply(FUN=sum, adaptive=TRUE, c(1:2,NA_real_), c(2,0,2), na.rm=TRUE), c(NA,0,2))
1064+
1065+
test(6001.311, frollmax(1:3, 0), c(-Inf,-Inf,-Inf), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1066+
test(6001.312, frollmax(1:3, 0, fill=99), c(-Inf,-Inf,-Inf))
1067+
test(6001.313, frollmax(c(1:2,NA), 0), c(-Inf,-Inf,-Inf))
1068+
test(6001.314, frollmax(c(1:2,NA), 0, na.rm=TRUE), c(-Inf,-Inf,-Inf))
1069+
test(6001.315, frollmax(1:3, 0, algo="exact"), c(-Inf,-Inf,-Inf), options=c("datatable.verbose"=TRUE), output="window width of size 0")
1070+
test(6001.316, frollmax(c(1:2,NA), 0, algo="exact"), c(-Inf,-Inf,-Inf))
1071+
test(6001.317, frollmax(c(1:2,NA), 0, algo="exact", na.rm=TRUE), c(-Inf,-Inf,-Inf))
1072+
test(6001.321, frollmax(adaptive=TRUE, 1:3, c(2,0,2)), c(NA,-Inf,3))
1073+
test(6001.322, frollmax(adaptive=TRUE, 1:3, c(2,0,2), fill=99), c(99,-Inf,3))
1074+
test(6001.323, frollmax(adaptive=TRUE, c(1:2,NA), c(2,0,2)), c(NA,-Inf,NA))
1075+
test(6001.324, frollmax(adaptive=TRUE, c(1:2,NA), c(2,0,2), na.rm=TRUE), c(NA,-Inf,2))
1076+
test(6001.325, frollmax(adaptive=TRUE, 1:3, c(2,0,2), algo="exact"), c(NA,-Inf,3))
1077+
test(6001.326, frollmax(adaptive=TRUE, 1:3, c(2,0,2), fill=99, algo="exact"), c(99,-Inf,3))
1078+
test(6001.327, frollmax(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact"), c(NA,-Inf,NA))
1079+
test(6001.328, frollmax(adaptive=TRUE, c(1:2,NA), c(2,0,2), algo="exact", na.rm=TRUE), c(NA,-Inf,2))
1080+
test(6001.329, frollmax(adaptive=TRUE, c(1:2,NA), c(2,0,2), fill=99, algo="exact", na.rm=TRUE), c(99,-Inf,2))
1081+
test(6001.381, frollapply(FUN=max, 1:3, 0), c(-Inf,-Inf,-Inf))
1082+
test(6001.382, frollapply(FUN=max, 1:3, 0, fill=99), c(-Inf,-Inf,-Inf))
1083+
test(6001.383, frollapply(FUN=max, c(1:2,NA_real_), 0), c(-Inf,-Inf,-Inf))
1084+
test(6001.384, frollapply(FUN=max, c(1:2,NA_real_), 0, na.rm=TRUE), c(-Inf,-Inf,-Inf))
1085+
test(6001.3910, frollapply(FUN = max, adaptive = TRUE, as.numeric(1:3), c(2,0,2)), c(NA, -Inf, 3))
1086+
test(6001.3911, frollapply(FUN=max, adaptive=TRUE, list(as.numeric(1:3), as.numeric(2:4)), c(2,0,2)), list(c(NA,-Inf,3), c(NA,-Inf,4)))
1087+
test(6001.3912, frollapply(FUN=max, adaptive=TRUE, as.numeric(1:3), list(c(2,0,2), c(0,2,0))), list(c(NA,-Inf,3), c(-Inf,2,-Inf)))
1088+
test(6001.3913, frollapply(FUN=max, adaptive=TRUE, list(as.numeric(1:3), as.numeric(2:4)), list(c(2,0,2), c(0,2,0))), list(c(NA,-Inf,3), c(-Inf,2,-Inf), c(NA,-Inf,4), c(-Inf,3,-Inf)))
1089+
test(6001.392, frollapply(FUN=max, adaptive=TRUE, as.numeric(1:3), c(2,0,2), fill=99), c(99,-Inf,3))
1090+
test(6001.393, frollapply(FUN=max, adaptive=TRUE, c(1:2,NA_real_), c(2,0,2)), c(NA,-Inf,NA))
1091+
test(6001.394, frollapply(FUN=max, adaptive=TRUE, c(1:2,NA_real_), c(2,0,2), na.rm=TRUE), c(NA,-Inf,2))
1092+
10091093
## partial
10101094
x = 1:6/2
10111095
n = 3
@@ -1515,8 +1599,10 @@ rollfun = function(x, n, FUN, fill=NA_real_, na.rm=FALSE, nf.rm=FALSE, partial=F
15151599
f = match.fun(FUN)
15161600
if (nf.rm) x[is.infinite(x)] = NA_real_
15171601
for (i in seq_along(x)) {
1518-
ans[i] = if (i >= n)
1519-
f(x[(i-n+1):i], na.rm=na.rm)
1602+
ans[i] = if (n==0)
1603+
f(x[integer()], na.rm=na.rm)
1604+
else if (i >= n)
1605+
f(x[(i-n+1L):i], na.rm=na.rm)
15201606
else if (partial)
15211607
f(x[max((i-n+1), 1L):i], na.rm=na.rm)
15221608
else
@@ -1569,6 +1655,8 @@ x = makeNA(rnorm(1e3), nf=TRUE); n = 51
15691655
base_compare(x, n)
15701656
x = makeNA(rnorm(1e3+1), nf=TRUE); n = 51
15711657
base_compare(x, n)
1658+
x = makeNA(rnorm(1e3), nf=TRUE); n = 0
1659+
base_compare(x, n)
15721660

15731661
#### against zoo
15741662
if (requireNamespace("zoo", quietly=TRUE)) {
@@ -1652,14 +1740,18 @@ arollfun = function(FUN, x, n, na.rm=FALSE, align=c("right","left"), fill=NA, nf
16521740
f = match.fun(FUN)
16531741
if (align=="right") {
16541742
for (i in seq_along(x)) {
1655-
if (i >= n[i])
1743+
if (n[i] == 0)
1744+
ans[i] = f(x[integer()], na.rm=na.rm)
1745+
else if (i >= n[i])
16561746
ans[i] = f(x[(i-n[i]+1L):i], na.rm=na.rm)
16571747
else if (partial)
16581748
ans[i] = f(x[1L:i], na.rm=na.rm)
16591749
}
16601750
} else {
16611751
for (i in seq_along(x)) {
1662-
if (i <= nx-n[i]+1)
1752+
if (n[i] == 0)
1753+
ans[i] = f(x[integer()], na.rm=na.rm)
1754+
else if (i <= nx-n[i]+1)
16631755
ans[i] = f(x[i:(i+n[i]-1L)], na.rm=na.rm)
16641756
else if (partial)
16651757
ans[i] = f(x[i:length(x)], na.rm=na.rm)
@@ -1719,6 +1811,8 @@ x = rnorm(1e3); n = sample(51, length(x), TRUE) # x even, n odd
17191811
afun_compare(x, n)
17201812
x = rnorm(1e3+1); n = sample(51, length(x), TRUE) # x odd, n odd
17211813
afun_compare(x, n)
1814+
x = rnorm(1e3); n = sample(0:49, length(x), TRUE) # x even, n even
1815+
afun_compare(x, n)
17221816
#### leading and trailing NAs
17231817
x = c(rep(NA, 60), rnorm(1e3), rep(NA, 60)); n = sample(50, length(x), TRUE)
17241818
afun_compare(x, n)
@@ -1728,6 +1822,8 @@ x = c(rep(NA, 60), rnorm(1e3), rep(NA, 60)); n = sample(51, length(x), TRUE)
17281822
afun_compare(x, n)
17291823
x = c(rep(NA, 60), rnorm(1e3+1), rep(NA, 60)); n = sample(51, length(x), TRUE)
17301824
afun_compare(x, n)
1825+
x = c(rep(NA, 60), rnorm(1e3), rep(NA, 60)); n = sample(0:49, length(x), TRUE)
1826+
afun_compare(x, n)
17311827
#### random NA
17321828
x = makeNA(rnorm(1e3)); n = sample(50, length(x), TRUE)
17331829
afun_compare(x, n)
@@ -1737,6 +1833,8 @@ x = makeNA(rnorm(1e3)); n = sample(51, length(x), TRUE)
17371833
afun_compare(x, n)
17381834
x = makeNA(rnorm(1e3+1)); n = sample(51, length(x), TRUE)
17391835
afun_compare(x, n)
1836+
x = makeNA(rnorm(1e3)); n = sample(0:49, length(x), TRUE)
1837+
afun_compare(x, n)
17401838
#### random NA non-finites
17411839
x = makeNA(rnorm(1e3), nf=TRUE); n = sample(50, length(x), TRUE)
17421840
afun_compare(x, n)
@@ -1746,4 +1844,6 @@ x = makeNA(rnorm(1e3), nf=TRUE); n = sample(51, length(x), TRUE)
17461844
afun_compare(x, n)
17471845
x = makeNA(rnorm(1e3+1), nf=TRUE); n = sample(51, length(x), TRUE)
17481846
afun_compare(x, n)
1847+
x = makeNA(rnorm(1e3), nf=TRUE); n = sample(0:49, length(x), TRUE)
1848+
afun_compare(x, n)
17491849
rm(num)

man/froll.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
}
2626
\arguments{
2727
\item{x}{ Vector, \code{data.frame} or \code{data.table} of integer, numeric or logical columns over which to calculate the windowed aggregations. May also be a list, in which case the rolling function is applied to each of its elements. }
28-
\item{n}{ Integer vector giving rolling window size(s). This is the \emph{total} number of included values in aggregate function. Adaptive rolling functions also accept a list of integer vectors when applying multiple window sizes. }
28+
\item{n}{ Integer, non-negative, vector giving rolling window size(s). This is the \emph{total} number of included values in aggregate function. Adaptive rolling functions also accept a list of integer vectors when applying multiple window sizes. }
2929
\item{fill}{ Numeric; value to pad by. Defaults to \code{NA}. }
3030
\item{algo}{ Character, default \code{"fast"}. When set to \code{"exact"}, a slower (but more accurate) algorithm is used. It
3131
suffers less from floating point rounding errors by performing an extra pass, and carefully handles all non-finite values.

0 commit comments

Comments
 (0)