Skip to content

Commit 2595a19

Browse files
authored
Merge branch 'master' into constnessImprovements
2 parents e8b4571 + c5e8152 commit 2595a19

File tree

11 files changed

+1043
-52
lines changed

11 files changed

+1043
-52
lines changed

.gitlab-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ test-lin-dev-gcc-strict-cran:
182182
- R CMD check --as-cran $(ls -1t data.table_*.tar.gz | head -n 1)
183183
- (! grep "warning:" data.table.Rcheck/00install.out)
184184
- >-
185-
Rscript -e 'l=tail(readLines("data.table.Rcheck/00check.log"), 1L); notes<-"Status: 3 NOTEs"; if (!identical(l, notes)) stop("Last line of ", shQuote("00check.log"), " is not ", shQuote(notes), " (size of tarball, non-API calls, V8 package) but ", shQuote(l)) else q("no")'
185+
Rscript -e 'l=tail(readLines("data.table.Rcheck/00check.log"), 1L); notes<-"Status: 2 NOTEs"; if (!identical(l, notes)) stop("Last line of ", shQuote("00check.log"), " is not ", shQuote(notes), " (non-API calls, V8 package) but ", shQuote(l)) else q("no")'
186186
187187
## R-devel on Linux clang
188188
# R compiled with clang, flags removed: -flto=auto -fopenmp
@@ -205,7 +205,7 @@ test-lin-dev-clang-cran:
205205
- R CMD check --as-cran $(ls -1t data.table_*.tar.gz | head -n 1)
206206
- (! grep "warning:" data.table.Rcheck/00install.out)
207207
- >-
208-
Rscript -e 'l=tail(readLines("data.table.Rcheck/00check.log"), 1L); notes<-"Status: 3 NOTEs"; if (!identical(l, notes)) stop("Last line of ", shQuote("00check.log"), " is not ", shQuote(notes), " (size of tarball, non-API calls, V8 package) but ", shQuote(l)) else q("no")'
208+
Rscript -e 'l=tail(readLines("data.table.Rcheck/00check.log"), 1L); notes<-"Status: 2 NOTEs"; if (!identical(l, notes)) stop("Last line of ", shQuote("00check.log"), " is not ", shQuote(notes), " (non-API calls, V8 package) but ", shQuote(l)) else q("no")'
209209
210210
# stated dependency on R
211211
test-lin-ancient-cran:

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export(frollsum)
5757
export(frollmax)
5858
export(frollmin)
5959
export(frollprod)
60+
export(frollmedian)
6061
export(frollapply)
6162
export(frolladapt)
6263
export(nafill)

NEWS.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,51 @@
246246
#9: 2025-09-22 9 8 9.0
247247
```
248248

249-
19. New rolling functions, `frollmin` and `frollprod`, have been implemented, towards [#2778](https://github.com/Rdatatable/data.table/issues/2778). Thanks to @jangorecki for implementation.
249+
19. New rolling functions: `frollmin`, `frollprod` and `frollmedian`, have been implemented, towards [#2778](https://github.com/Rdatatable/data.table/issues/2778). Thanks to @jangorecki for implementation. Implementation of rolling median is based on a novel algorithm "sort-median" described by [@suomela](https://github.com/suomela) in his 2014 paper [Median Filtering is Equivalent to Sorting](https://arxiv.org/abs/1406.1717). "sort-median" scales very well, not only for size of input vector but also for size of rolling window.
250+
```r
251+
rollmedian = function(x, n) {
252+
ans = rep(NA_real_, nx<-length(x))
253+
if (n<=nx) for (i in n:nx) ans[i] = median(x[(i-n+1L):(i)])
254+
ans
255+
}
256+
library(data.table)
257+
setDTthreads(8)
258+
set.seed(108)
259+
x = rnorm(1e5)
260+
261+
n = 100
262+
system.time(rollmedian(x, n))
263+
# user system elapsed
264+
# 2.049 0.001 2.051
265+
system.time(frollapply(x, n, median, simplify=unlist))
266+
# user system elapsed
267+
# 3.071 0.223 0.436
268+
system.time(frollmedian(x, n))
269+
# user system elapsed
270+
# 0.013 0.000 0.004
271+
272+
n = 1000
273+
system.time(rollmedian(x, n))
274+
# user system elapsed
275+
# 3.496 0.009 3.507
276+
system.time(frollapply(x, n, median, simplify=unlist))
277+
# user system elapsed
278+
# 4.552 0.307 0.632
279+
system.time(frollmedian(x, n))
280+
# user system elapsed
281+
# 0.015 0.000 0.004
282+
283+
n = 10000
284+
system.time(rollmedian(x, n))
285+
# user system elapsed
286+
# 16.350 0.025 16.382
287+
system.time(frollapply(x, n, median, simplify=unlist))
288+
# user system elapsed
289+
# 14.865 0.722 2.267
290+
system.time(frollmedian(x, n))
291+
# user system elapsed
292+
# 0.028 0.000 0.005
293+
```
250294

251295
### BUG FIXES
252296

R/froll.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,6 @@ frollmin = function(x, n, fill=NA, algo=c("fast","exact"), align=c("right","left
213213
frollprod = function(x, n, fill=NA, algo=c("fast","exact"), align=c("right","left","center"), na.rm=FALSE, has.nf=NA, adaptive=FALSE, partial=FALSE, give.names=FALSE, hasNA) {
214214
froll(fun="prod", x=x, n=n, fill=fill, algo=algo, align=align, na.rm=na.rm, has.nf=has.nf, adaptive=adaptive, partial=partial, hasNA=hasNA, give.names=give.names)
215215
}
216+
frollmedian = function(x, n, fill=NA, algo=c("fast","exact"), align=c("right","left","center"), na.rm=FALSE, has.nf=NA, adaptive=FALSE, partial=FALSE, give.names=FALSE, hasNA) {
217+
froll(fun="median", x=x, n=n, fill=fill, algo=algo, align=align, na.rm=na.rm, has.nf=has.nf, adaptive=adaptive, partial=partial, hasNA=hasNA, give.names=give.names)
218+
}

0 commit comments

Comments
 (0)