| Type: | Package |
| Title: | STL with Extended Capabilities |
| Version: | 0.1.0 |
| Description: | Implements a Seasonal-Trend decomposition procedure based on LOESS (STL, developed by Cleveland, Cleveland, McRae, and Terpenning, 1990) in 'R' and 'C++'. The package supports missing values, fractional seasonal periods, multiplicative decompositions, and cross-validation based selection of the seasonal smoothing window. |
| License: | GPL (≥ 3) |
| Encoding: | UTF-8 |
| Imports: | Rcpp |
| LinkingTo: | Rcpp |
| Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| VignetteBuilder: | knitr |
| Config/roxygen2/version: | 8.1.1 |
| NeedsCompilation: | yes |
| Packaged: | 2026-10-23 14:32:49 UTC; s3504do |
| Author: | Daniel Ollech [aut, cre], Pavithra Purushothaman [ctb] |
| Maintainer: | Daniel Ollech <daniel.ollech@bundesbank.de> |
| Repository: | CRAN |
| Date/Publication: | 2026-11-07 14:50:07 UTC |
Calculate an error metric between two series
Description
Computes a scalar error metric between two numeric vectors, such as MAE, MSE, or RMSE.
Usage
calculate_error_metric(x, y, error_metric = "RMSE")
Arguments
x |
Numeric vector of fitted or predicted values. |
y |
Numeric vector of observed values, same length as |
error_metric |
Character string specifying the error metric. One of
|
Details
The metrics are defined as:
-
"mae": mean absolute error. -
"mse": mean squared error. -
"rmse": root mean squared error.
Non-finite values are omitted from the calculation. If no finite paired
observations remain, NA is returned.
Value
Numeric scalar, the value of the chosen error metric.
Author(s)
Daniel Ollech
Moving average over a non-integer number of observations
Description
Moving average over a non-integer number of observations
Usage
fractional_moving_average(x, p, reverse = FALSE)
Arguments
x |
Numeric vector. |
p |
Numeric (>= 1). Span of the moving average in observations. |
reverse |
Logical. If |
Details
Averages floor(p) observations with weight 1 / p each and one
further observation with weight (p - floor(p)) / p. For integer
p this equals simple_moving_average.
Value
Numeric vector of length length(x) - ceiling(p) + 1.
Author(s)
Daniel Ollech
Impute missing values using local regression
Description
Replaces NA values in a series by local regression estimates based on
neighboring observations.
Usage
impute_missing_localreg(y, window = 7, ideg = 0, userw = FALSE, rw = NULL)
Arguments
y |
Numeric vector possibly containing |
window |
Integer. Window length used for the local regression around each missing value. |
ideg |
Integer (0 or 1). Degree of local polynomial (0 = local mean, 1 = local linear). |
userw |
Logical. If |
rw |
Optional numeric vector of robustness weights, same length as |
Details
For each missing value, a local regression is fitted using
local_regression on the available neighbors within the
specified window, and the missing value is replaced by the fitted value.
Value
Numeric vector of the same length as y, with missing values imputed.
Author(s)
Daniel Ollech
See Also
Local regression at a single point
Description
Performs a local regression (degree 0 or 1) at a single target index using tricube weights and optional robustness weights.
Usage
local_regression(y, len, ideg, xs, nleft, nright, userw, rw)
Arguments
y |
Numeric vector. Input time series. |
len |
Integer. Window length for the local regression. |
ideg |
Integer (0 or 1). Degree of local polynomial (0 = local mean, 1 = local linear). |
xs |
Integer. Target index at which the fit is evaluated (1-based). |
nleft |
Integer. Left bound of the window (1-based). |
nright |
Integer. Right bound of the window (1-based). |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
Details
The function constructs a local neighborhood around xs, computes
tricube distance weights, optionally multiplies them by robustness weights,
and then fits either a local mean or local linear model. Missing values in
y are automatically excluded.
Value
A list with components:
ok |
Logical. |
ys |
Numeric scalar. Fitted value at |
weights |
Numeric vector of normalized weights used in the fit. |
Author(s)
Daniel Ollech
Plot an STL decomposition fitted by stlpro Plot the reconstructed observed series and its seasonal, trend, and remainder components.
Description
Plot an STL decomposition fitted by stlpro
Plot the reconstructed observed series and its seasonal, trend, and remainder components.
Usage
## S3 method for class 'stlpro'
plot(
x,
plot_type = c("multiple", "single"),
multiplicative = NULL,
xlab = "",
ylab = "data",
main = NULL,
labels = c("Unadjusted and adjusted series", "Seasonal component", "Trend component",
"Remainder component"),
col = c("#071108", "#D31B0D", "#d35e13", "#417246", "#2274A5"),
lwd = 1,
...
)
Arguments
x |
An object returned by |
plot_type |
Either |
multiplicative |
Logical. Is the decomposition multiplicative?
If |
xlab |
Label for the x-axis. |
ylab |
Label for the y-axis of the observed-data panel. |
main |
Optional overall plot title. |
labels |
Optional character vector of length four giving labels for the observed, seasonal, trend, and remainder panels. |
col |
Colours used for the observed, seasonally adjusted, seasonal, trend, and remainder series, respectively. |
lwd |
Line width. |
... |
Further graphical parameters passed to |
Value
Invisibly returns x.
Print method for cross-validation results
Description
Pretty-prints an object of class "cv_results".
Usage
## S3 method for class 'cv_results'
print(x, ...)
Arguments
x |
Object of class |
... |
Currently ignored. |
Value
Invisibly returns the printed character string.
Author(s)
Daniel Ollech
Run cross-validation for the seasonal window
Description
Evaluates several candidate seasonal window lengths via cross-validation and selects the one that minimizes a chosen error metric.
Usage
run_cross_validation(
work1,
period,
s_window_candidates,
s_degree,
s_jump,
userw,
rw,
error_metric
)
Arguments
work1 |
Numeric vector. Trend-adjusted series (e.g., |
period |
Numeric. Seasonal period (e.g., 12 for monthly data); may be non-integer. |
s_window_candidates |
Integer vector of candidate seasonal window lengths. |
s_degree |
Integer (0 or 1). Degree of local polynomial for the seasonal smoother. |
s_jump |
Integer. Jump (subsampling) parameter for the seasonal smoother. |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
error_metric |
Character string specifying the error metric. One of
|
Details
For each candidate window length, the function computes a seasonal component
using stl_subseries_smoother_cv and evaluates the discrepancy
between the seasonal component and work1 using
calculate_error_metric. It will never approve s_window = 3, because this window size does not smooth the data, the weights in the local regression is (0,1,0), so no smoothing occurs. Technically s_window = 3 drops out, because for the comparison of the cross-validation errors only time points that could be removed and still be smoothed are considered.
Value
An object of class "cv_results", which is a list with components:
cv_choice |
Integer. Selected seasonal window length. |
error_metrics |
Named numeric vector of error metric values for each candidate. |
Author(s)
Daniel Ollech
See Also
stl_subseries_smoother_cv, calculate_error_metric,
print.cv_results
Simple moving average
Description
Computes a simple moving average of a numeric vector with a fixed window length.
Usage
simple_moving_average(x, len)
Arguments
x |
Numeric vector. |
len |
Integer. Window length for the moving average. |
Details
The result has length length(x) - len + 1. If len is larger
than length(x), an error is thrown.
Value
Numeric vector of moving average values.
Author(s)
Daniel Ollech
Single STL decomposition run with optional seasonal window cross-validation
Description
Performs one STL-like decomposition step given a current trend estimate, optionally choosing the seasonal window via cross-validation.
Usage
single_stl_run(
y,
trend,
userw,
rw,
period,
s_window,
s_degree,
s_jump,
l_window,
l_degree,
l_jump,
t_window,
t_degree,
t_jump,
s_window_candidates,
error_metric,
first_round,
multiplicative
)
Arguments
y |
Numeric vector. Original time series. |
trend |
Numeric vector of the same length as |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
period |
Numeric. Seasonal period (e.g., 12 for monthly data, 4 for quarterly).
May be non-integer, e.g. |
s_window |
Either an integer seasonal window length, |
s_degree |
Integer (0 or 1). Degree of local polynomial for seasonal smoothing. |
s_jump |
Integer. Jump (subsampling) parameter for seasonal smoothing. |
l_window |
Integer. Window length for the low-pass smoother applied to the preliminary seasonal component. |
l_degree |
Integer (0 or 1). Degree of local polynomial for the low-pass smoother. |
l_jump |
Integer. Jump (subsampling) parameter for the low-pass smoother. |
t_window |
Integer. Window length for the trend smoother. |
t_degree |
Integer (0 or 1). Degree of local polynomial for the trend smoother. |
t_jump |
Integer. Jump (subsampling) parameter for the trend smoother. |
s_window_candidates |
Integer vector of candidate seasonal window lengths
to be evaluated when |
error_metric |
Character string specifying the error metric used in
cross-validation. One of |
first_round |
Logical. If |
multiplicative |
Logical. If |
Details
The function:
Computes a trend-adjusted series
Y - T.Obtains a preliminary seasonal component via
stl_subseries_smoother.Applies a low-pass filter and smoothing to obtain a smooth seasonal mean.
Derives the seasonal component as the difference between the preliminary seasonal and the low-pass component.
Computes the seasonally adjusted series
Y - S.Re-estimates the trend via
stl_full_smoother.
If s_window is NULL or "cv", the seasonal window is chosen
by run_cross_validation using s_window_candidates.
Value
A list with components:
season |
Numeric vector of seasonal component estimates. |
trend |
Numeric vector of trend estimates. |
use_swindow |
Integer. Seasonal window length actually used. |
cv_results |
Object of class |
Author(s)
Daniel Ollech
See Also
stl_subseries_smoother, stl_full_smoother,
run_cross_validation
Enhanced STL Decomposition
Description
Decompose a time series into seasonal, trend, and remainder components using STL, optionally with robust fitting. Compare to stats::stl it included cross-validation, multiplicative decompositions, allows non-integer seasonal periods and can handle missing values.
Usage
stl(
y,
period = NULL,
multiplicative = FALSE,
s_window = NULL,
t_window = NULL,
l_window = NULL,
s_degree = 0,
t_degree = 1,
l_degree = 1,
s_jump = NULL,
t_jump = NULL,
l_jump = NULL,
inner = NULL,
outer = 0,
robust = NULL,
s_window_candidates = c(7, 9, 13, 19, 37),
error_metric = "RMSE"
)
Arguments
y |
Numeric vector or time series. |
period |
Seasonal period, can be non-integer. If NULL and y is ts, uses frequency(y). |
multiplicative |
Logical. If TRUE a multiplicative decomposition is calculated, additive otherwise. |
s_window |
Seasonal window (odd integer >= 3). If NULL, is set using cross-validation. |
t_window |
Trend window (odd integer >= 3). If NULL, uses the default, namely nextodd(ceiling((1.5*period) / (1-(1.5/s_window)))). |
l_window |
Low-pass window (odd integer >= 3). If NULL, uses default. |
s_degree |
Degree of locally-fitted polynomial in seasonal smoothing (0 or 1). |
t_degree |
Degree of locally-fitted polynomial in trend smoothing (0 or 1). |
l_degree |
Degree of locally-fitted polynomial in low-pass smoothing (0 or 1). |
s_jump |
Seasonal jump (integer >= 1). If NULL, uses default. |
t_jump |
Trend jump (integer >= 1). If NULL, uses default. |
l_jump |
Low-pass jump (integer >= 1). If NULL, uses default. |
inner |
Number of inner iterations. If |
outer |
Number of outer robustifying iterations (default |
robust |
Logical scalar controlling the robustness iteration settings. If |
s_window_candidates |
Candidates for cross-validation based selection
of |
error_metric |
Error metric used for cross-validation: |
Details
Values of period that are within 1e-8 of an integer are rounded to that
integer. Values must be finite scalars greater than 1.
Value
A list with components: seasonal, trend, remainder, sa, weights, call, cv_results.
Author(s)
Daniel Ollech
Loess smoother over an entire series with optional skipping
Description
Applies a local regression smoother over a univariate series, optionally
evaluating the smoother only at every njump-th point and linearly
interpolating in between.
Usage
stl_full_smoother(y, len, ideg, njump, userw, rw)
Arguments
y |
Numeric vector. Input time series. |
len |
Integer. Window length for the local regression. |
ideg |
Integer (0 or 1). Degree of local polynomial (0 = local mean, 1 = local linear). |
njump |
Integer. Jump (subsampling) parameter. If |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
Details
The function calls local_regression at selected indices and
fills in skipped points by linear interpolation when njump > 1.
Value
Numeric vector of smoothed values, same length as y.
Author(s)
Daniel Ollech
See Also
STL low-pass filter
Description
Applies a low-pass filter used in STL decomposition, consisting of two
moving averages of length period followed by a moving average of length 3.
Usage
stl_lowpassfilter(x, period)
Arguments
x |
Numeric vector. Input series. |
period |
Numeric. Seasonal period (e.g., 12 for monthly data); may be non-integer. |
Details
The filter is:
Moving average of length
period.Moving average of length
periodof the result.Moving average of length 3 of the result.
For non-integer period, a moving average of length period averages
ceiling(period) observations, the last one with the weight of the
fractional part only (see fractional_moving_average). The
second average is mirrored, so the combined filter stays centred.
For integer period this is exactly the classic STL low-pass filter.
Value
Numeric vector of filtered values, of length
length(x) - 2 * ceiling(period).
Author(s)
Daniel Ollech
See Also
simple_moving_average, fractional_moving_average
Check and normalize the seasonal period
Description
Periods within 1e-8 of an integer are treated as that integer, so that
e.g. 12.000000001 takes the faster integer code paths.
Usage
stl_period(period)
Arguments
period |
Numeric scalar, the seasonal period (> 1). |
Value
period, rounded if it is numerically an integer.
Author(s)
Daniel Ollech
Compute robustness weights for STL
Description
Computes robustness weights based on residuals between the observed series and a fitted component, following the robust STL scheme.
Usage
stl_robustness_weights(y, fit)
Arguments
y |
Numeric vector. Observed series. |
fit |
Numeric vector. Fitted values (e.g., trend + seasonal). |
Details
The weights are based on the absolute residuals |y - fit| and a
scaled median absolute deviation. Observations with small residuals get
weight 1, and those with large residuals are down-weighted smoothly.
Value
Numeric vector of robustness weights in [0, 1], same length as y.
Author(s)
Daniel Ollech
Seasonal subseries smoother
Description
Smooths every cycle-subseries with loess and extrapolates n_ext values at
both ends. The period may be non-integer (e.g. 365.25 / 7 for weekly
data): then the subseries through each time point t consists of the values
at t + k * period, interpolated linearly where they fall between two
observations, and the smooth is evaluated at t.
Usage
stl_subseries_smoother(
y,
period,
ns,
isdeg,
nsjump,
userw,
rw,
n_ext = NULL,
loo = FALSE
)
Arguments
y |
Numeric vector. Input time series. |
period |
Numeric. Seasonal period (e.g., 12 for monthly data); may be non-integer. |
ns |
Integer. Window length for the local regression within each subseries. |
isdeg |
Integer (0 or 1). Degree of local polynomial for the subseries smoother. |
nsjump |
Integer. Jump (subsampling) parameter for the subseries smoother. |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
n_ext |
Integer number of extension values at each end. Defaults to
|
loo |
Logical. If |
Details
For integer period, the function extracts for each seasonal position
j = 1, ..., period the subseries y[j], y[j + period], ..., smooths it
with loess and extrapolates one value at both ends.
For non-integer period (and for loo = TRUE or
n_ext != period), every time point t gets its own subseries
t + k * period; positions between two observations are interpolated
linearly. For integer period both ways give the same result.
Value
Numeric vector of length length(y) + 2 * n_ext containing the
smoothed seasonal component with extra values at both ends; element m
belongs to time point m - n_ext.
Author(s)
Daniel Ollech
See Also
stl_full_smoother, local_regression
Seasonal subseries smoother for cross-validation
Description
Variant of stl_subseries_smoother used for cross-validation,
returning a seasonal component of the same length as the input series.
Usage
stl_subseries_smoother_cv(y, period, ns, isdeg, nsjump, userw, rw)
Arguments
y |
Numeric vector. Input time series. |
period |
Numeric. Seasonal period (e.g., 12 for monthly data); may be non-integer. |
ns |
Integer. Window length for the local regression within each subseries. |
isdeg |
Integer (0 or 1). Degree of local polynomial for the subseries smoother. |
nsjump |
Integer. Jump (subsampling) parameter for the subseries smoother. |
userw |
Logical. If |
rw |
Numeric vector of robustness weights, same length as |
Details
Each fitted value is obtained by leaving out its own observation
(leave-one-out). With nsjump > 1, values between the fitted points
are interpolated linearly, as in stl_full_smoother. If a
leave-one-out fit fails (no other observation with positive weight in the
window), the observation itself is returned.
Value
Numeric vector of length length(y) containing the smoothed
seasonal component.
Author(s)
Daniel Ollech