Skip to content

Conversation

@jangorecki
Copy link
Member

@jangorecki jangorecki commented Sep 14, 2025

New rolling function: median. Towards #2778

Supersede #5692


Implementation of rolling median is based on a novel algorithm "sort-median" described by @suomela in 2014 in his paper Median Filtering is Equivalent to Sorting. "sort-median" scales very well, not only for size of input vector but also for size of rolling window. Implementation here is extended to address following limitations present in the paper:

  • size of input vector must by divisible by window size
  • window size must be an uneven number

Thanks to Jukka for the paper and hints on extending the algo.

rollmedian = function(x, n) {
  ans = rep(NA_real_, nx<-length(x))
  if (n<=nx) for (i in n:nx) ans[i] = median(x[(i-n+1L):(i)])
  ans
}
library(data.table)
setDTthreads(8)
set.seed(108)
x = rnorm(1e5)

n = 100
system.time(rollmedian(x, n))
#   user  system elapsed
#  2.049   0.001   2.051
system.time(frollapply(x, n, median, simplify=unlist))
#   user  system elapsed
#  3.071   0.223   0.436
system.time(frollmedian(x, n))
#   user  system elapsed
#  0.013   0.000   0.004

n = 1000
system.time(rollmedian(x, n))
#   user  system elapsed
#  3.496   0.009   3.507
system.time(frollapply(x, n, median, simplify=unlist))
#   user  system elapsed
#  4.552   0.307   0.632
system.time(frollmedian(x, n))
#   user  system elapsed
#  0.015   0.000   0.004

n = 10000
system.time(rollmedian(x, n))
#   user  system elapsed
# 16.350   0.025  16.382
system.time(frollapply(x, n, median, simplify=unlist))
#   user  system elapsed
# 14.865   0.722   2.267
system.time(frollmedian(x, n))
#   user  system elapsed
#  0.028   0.000   0.005

This work was supported by the Medical Research Council, UK [grant number 1573].

@jangorecki jangorecki added this to the 1.18.0 milestone Sep 14, 2025
@jangorecki jangorecki mentioned this pull request Sep 14, 2025
@codecov
Copy link

codecov bot commented Sep 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.11%. Comparing base (6f225f3) to head (d379478).
⚠️ Report is 22 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7315      +/-   ##
==========================================
+ Coverage   99.09%   99.11%   +0.01%     
==========================================
  Files          83       85       +2     
  Lines       16092    16440     +348     
==========================================
+ Hits        15947    16295     +348     
  Misses        145      145              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link

github-actions bot commented Sep 14, 2025

No obvious timing issues in HEAD=frollmedian
Comparison Plot

Generated via commit d379478

Download link for the artifact containing the test results: ↓ atime-results.zip

Task Duration
R setup and installing dependencies 2 minutes and 57 seconds
Installing different package versions 42 seconds
Running and plotting the test cases 2 minutes and 52 seconds

@jangorecki
Copy link
Member Author

Updated timings in https://github.com/jangorecki/rollbench

Copy link
Contributor

@mcol mcol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some grammar fixes/suggestions.

@jangorecki

This comment was marked as resolved.

@jangorecki jangorecki merged commit c5e8152 into master Oct 3, 2025
12 checks passed
@jangorecki jangorecki deleted the frollmedian branch October 3, 2025 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants