Overview
Streaming LOWESS processes data in fixed-size chunks with a
configurable overlap. Points inside the overlap zone are fitted twice —
once by the left chunk and once by the right chunk. The
merge_strategy decides how those two estimates are
combined.
Chunk A: [=========|=====]
Chunk B: [=====|=========]
Overlap: [=====]
↑
merge_strategy
applied here
| Strategy | Method | Robustness | Speed |
|---|---|---|---|
"average" |
Simple mean of both estimates | Low | Fastest |
"take_first" |
Left-chunk estimate only | Low | Fastest |
"take_last" |
Right-chunk estimate only | Low | Fastest |
"weighted_average" |
Distance-weighted mean (default) | High | Moderate |
Weighted Average (Default)
Blends left- and right-chunk estimates using distance-based weights. Points closer to the centre of each chunk get higher weight.
Use when: General-purpose streaming; most reliable option.
library(rfastlowess)
set.seed(42)
x <- seq(0, 2 * pi, length.out = 100)
y <- sin(x) + rnorm(100, sd = 0.3)
x_chunk <- x[seq_len(50)]
y_chunk <- y[seq_len(50)]
model <- StreamingLowess(
chunk_size = 5000,
overlap = 500,
merge_strategy = "weighted_average"
)
result <- process_chunk(model, x_chunk, y_chunk)
cat("First 6 smoothed values (weighted_average strategy):\n")
#> First 6 smoothed values (weighted_average strategy):
print(head(result$y))
#> numeric(0)Average
Takes the arithmetic mean of the left-chunk and right-chunk estimates in the overlap region.
Use when: Chunks are large and the overlap region has uniform data density.
model <- StreamingLowess(
chunk_size = 5000,
overlap = 500,
merge_strategy = "average"
)
result <- process_chunk(model, x_chunk, y_chunk)
cat("First 6 smoothed values (average strategy):\n")
#> First 6 smoothed values (average strategy):
print(head(result$y))
#> numeric(0)Take First
Uses only the left-chunk estimate in the overlap region.
Use when: The left chunk has a larger context window and is expected to be more accurate at the overlap boundary.
model <- StreamingLowess(
chunk_size = 5000,
overlap = 500,
merge_strategy = "take_first"
)
result <- process_chunk(model, x_chunk, y_chunk)
cat("First 6 smoothed values (take_first strategy):\n")
#> First 6 smoothed values (take_first strategy):
print(head(result$y))
#> numeric(0)Take Last
Uses only the right-chunk estimate in the overlap region.
Use when: The right chunk is expected to provide better context (e.g., more data follows).
model <- StreamingLowess(
chunk_size = 5000,
overlap = 500,
merge_strategy = "take_last"
)
result <- process_chunk(model, x_chunk, y_chunk)
cat("First 6 smoothed values (take_last strategy):\n")
#> First 6 smoothed values (take_last strategy):
print(head(result$y))
#> numeric(0)Choosing Chunk Size and Overlap
| Consideration | Recommendation |
|---|---|
| Memory limit |
chunk_size = largest chunk that fits comfortably |
| Edge accuracy |
overlap ≥ fraction × chunk_size
|
| Speed | Larger chunks → fewer merges → faster |
# Rule of thumb: overlap = fraction * chunk_size
fraction <- 0.3
chunk_size <- 5000
overlap <- ceiling(fraction * chunk_size) # 1500
model <- StreamingLowess(
fraction = fraction,
chunk_size = chunk_size,
overlap = overlap,
merge_strategy = "weighted_average"
)
cat(sprintf("overlap = %d points (%.0f%% of chunk)\n",
overlap, 100 * overlap / chunk_size))
#> overlap = 1500 points (30% of chunk)Choosing a Strategy
| Situation | Recommended Strategy |
|---|---|
| General purpose | "weighted_average" |
| Maximum throughput | "average" |
| Immediate finalised output | "take_first" |
| Post-processing, right context better | "take_last" |
| Minimising boundary artefacts | "weighted_average" |
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.5 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
#> [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
#> [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
#> [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] rfastlowess_5.0.0
#>
#> loaded via a namespace (and not attached):
#> [1] digest_0.6.39 desc_1.4.3 R6_2.6.1 fastmap_1.2.0
#> [5] xfun_0.61 cachem_1.1.0 knitr_1.52 htmltools_0.5.9
#> [9] rmarkdown_2.32 lifecycle_1.0.5 cli_3.6.6 sass_0.4.10
#> [13] pkgdown_2.2.1 textshaping_1.0.5 jquerylib_0.1.4 systemfonts_1.3.2
#> [17] compiler_4.6.1 tools_4.6.1 ragg_1.5.2 bslib_0.12.0
#> [21] evaluate_1.0.5 yaml_2.3.12 otel_0.2.0 jsonlite_2.0.0
#> [25] rlang_1.3.0 fs_2.1.0 htmlwidgets_1.6.4