Extract trend components from time series objects using various econometric methods. Designed for monthly and quarterly economic data analysis. Returns trend components as time series objects or a list of time series.
Usage
extract_trends(
ts_data,
methods = "stl",
window = NULL,
smoothing = NULL,
band = NULL,
align = NULL,
params = list(),
.quiet = FALSE
)Arguments
- ts_data
A time series object (
ts,xts, orzoo) or any object convertible via tsbox. Missing values inside the observed span are rejected: methods disagree on what to do with them, and several fail silently. Impute them first. Leading and trailing missing values are excluded from estimation and returned asNA.- methods
Character vector of trend methods. Options:
"hp","bk","cf","ma","stl","loess","spline","poly","bn","ucm","hamilton","spencer","henderson","ewma","wma","triangular","kernel","kalman","median","gaussian". Default is"stl".- window
Unified window/period parameter for moving average methods (ma, wma, triangular, stl, ewma, median, gaussian, henderson). Must be positive. If NULL, uses frequency-appropriate defaults. For EWMA, the window is converted to the smoothing factor via
alpha = 2 / (window + 1). Cannot be used simultaneously withsmoothingfor EWMA method. Forma,median, andhendersonmethods, a numeric vector is accepted (e.g.,c(9, 13, 23)), which runs the method once per window value and returns a named list with keys likehenderson_9,henderson_13,henderson_23. Other methods ignore extra values (with a warning).- smoothing
Unified smoothing parameter for smoothing methods (hp, loess, spline, ewma, kernel, kalman). For hp: a value above 1 is lambda itself; a value of 1 or less is a fraction of the default lambda for the frequency,
1600 * (frequency / 4)^4. For EWMA: specifies the alpha parameter (0-1) for traditional exponential smoothing. Cannot be used simultaneously withwindowfor EWMA method. For kernel: multiplier of optimal bandwidth (1.0 = optimal, <1 = less smooth, >1 = more smooth). For kalman: a finite, positive ratio of measurement to process noise (higher = more smoothing). An explicit noise variance inparamsdetermines the other variance from this ratio. If both variances are supplied, they take precedence oversmoothing. Without a ratio, unspecified measurement and process variances default to 0.1 and 0.01 times the series variance. For others: typically 0-1 range.- band
Unified band parameter for bandpass filters (bk, cf). Provide as
c(low, high): the shortest and longest cycle to remove, in periods of the series (months for monthly data). Both values must be positive. Defaults to cycles of 1.5 to 8 years:c(6, 32)for quarterly data,c(18, 96)for monthly, andc(2, 8)for annual.- align
Unified alignment parameter for moving average methods (ma, wma, triangular, gaussian). Valid values:
"center"(default, uses surrounding values),"right"(causal, uses past values only),"left"(anti-causal, uses future values only). Note: triangular only supports"center"and"right". If NULL, uses"center"as default.- params
Optional list of method-specific parameters for fine control:
HP Filter:
hp_onesided(logical, default FALSE) - Use one-sided (real-time) filter instead of two-sidedSTL:
stl_s_windowors.window(numeric/"periodic", default "periodic") - Seasonal window,stl_t_windowort.window(numeric/NULL, default NULL) - Trend window,stl_robustorrobust(logical, default FALSE) - Use robust fitting. Note: Both dot notation (s.window) and underscore notation (stl_s_window) are accepted.Spline:
spline_cv(logical/NULL) - Cross-validation method: NULL (none), TRUE (leave-one-out), FALSE (GCV)Polynomial:
poly_degree(integer, default 1),poly_raw(logical, default FALSE for orthogonal polynomials)UCM:
ucm_type(character) - Model type: "level", "trend", or "BSM". Defaults to "BSM" for frequencies 2 to 12 and "level" otherwise. Explicit "BSM" requests require frequency at most 12.Others:
bn_ar_order,hamilton_h,hamilton_p,kernel_type,kalman_measurement_noise,kalman_process_noise,median_endrule,gaussian_sigma,wma_weights.Note: Alignment parameters (
ma_align,wma_align,triangular_align,gaussian_align) can still be passed viaparamsbut it's recommended to use the unifiedalignparameter instead.
- .quiet
If
TRUE, suppress informational messages.
Value
If single method, returns a ts object. If multiple methods, returns
a named list of ts objects.
Details
This function focuses on monthly (frequency = 12) and quarterly (frequency = 4) economic data. It uses established econometric methods with appropriate defaults:
HP Filter: lambda = 1600 (quarterly), 129600 (monthly), 6.25 (annual), following Ravn and Uhlig (2002). Supports both two-sided and one-sided (real-time) variants
Baxter-King: Bandpass filter for business cycles (1.5 to 8 years by default)
Christiano-Fitzgerald: Asymmetric bandpass filter
Moving Average: Centered, frequency-appropriate windows
STL: Seasonal-trend decomposition
Loess: Local polynomial regression
Spline: Smoothing splines
Polynomial: Linear/polynomial trends
Beveridge-Nelson: Permanent/transitory decomposition
UCM: Unobserved Components Model (basic structural model up to monthly data, local level otherwise)
Hamilton: Regression-based alternative to HP filter
Advanced MA: EWMA with various implementations
Kernel Smoother: Non-parametric regression with various kernel functions
Kalman Smoother: Adaptive filtering for noisy time series
Median Filter: Robust filtering using running medians to remove outliers
Gaussian Filter: Weighted average with Gaussian (normal) density weights
Parameter Usage Notes:
HP Filter: Use
hp_onesided=TRUEfor real-time analysis or when future data should not influence current estimates. One-sided filter is appropriate for nowcasting, policy analysis, and avoiding look-ahead bias. Default two-sided filter is optimal for historical analysis.EWMA: Use either
window(converted toalpha = 2 / (window + 1)) ORsmoothing(alpha parameter), not bothKalman: Use
smoothingparameter orparamslist for fine control of noise parametersSpline: Use
spline_cvto control cross-validation (NULL=none, TRUE=LOO-CV, FALSE=GCV)Polynomial: Use
poly_raw=FALSEfor orthogonal polynomials (more stable for degree > 2) orpoly_raw=TRUEfor raw polynomials. Warning issued for degree > 3 (overfitting risk).UCM: Choose model type - "level" (simplest), "trend" (time-varying slope), or "BSM" (with seasonal component, requires seasonal data). Variances are estimated by maximum likelihood, so
smoothingdoes not apply. The trend is the smoothed level. On seasonal data, "level" and "trend" can absorb the seasonality into the level and return the series itself, which is why the default is "BSM" up to monthly data. "BSM" carries one state per season and becomes very slow on weekly or daily data.
Examples
# Single method
hp_trend <- extract_trends(AirPassengers, methods = "hp")
#> Computing HP filter (two-sided) with lambda = 129600
# Multiple methods with unified smoothing
smooth_trends <- extract_trends(
AirPassengers,
methods = c("hp", "loess", "ewma"),
smoothing = 0.3
)
#> Computing HP filter (two-sided) with lambda = 38880
#> Computing loess trend with span = 0.3
#> Computing EWMA with alpha = 0.3
# EWMA with window (alpha derived from window size)
ewma_window <- extract_trends(AirPassengers, methods = "ewma", window = 12)
#> Computing EWMA with window = 12
# EWMA with alpha (traditional formula)
ewma_alpha <- extract_trends(AirPassengers, methods = "ewma", smoothing = 0.2)
#> Computing EWMA with alpha = 0.2
# Moving averages with unified window
ma_trends <- extract_trends(
AirPassengers,
methods = c("ma", "wma", "triangular"),
window = 8
)
#> Computing 2x8-period MA (auto-adjusted for even-window centering)
#> Computing 8-period weighted MA with linear weights, center alignment
#> Computing 8-period triangular MA with center alignment
# Bandpass filters with unified band
bp_trends <- extract_trends(
AirPassengers,
methods = c("bk", "cf"),
band = c(18, 96)
)
#> Warning: Series length (144) is less than recommended minimum (288) for Baxter-King
#> filter with pu = 96. Results may be unreliable.
#> Computing Baxter-King filter with bands [18, 96]
#> Computing Christiano-Fitzgerald filter with bands [18, 96]
# Moving average with right alignment (causal filter)
ma_causal <- extract_trends(
AirPassengers,
methods = "ma",
window = 12,
align = "right"
)
#> Computing 12-period MA with right alignment
# Signal processing methods with specific parameters
finance_trends <- extract_trends(
AirPassengers,
methods = c("kalman", "gaussian"),
window = 9, # For Gaussian filter
params = list(kalman_measurement_noise = 0.1) # Kalman-specific parameter
)
#> Computing Kalman smoother with measurement noise = {measurement_noise}
#> Computing 9-period Gaussian filter with sigma = 2.25, center alignment
# Spline with cross-validation options
spline_trends <- extract_trends(
AirPassengers,
methods = "spline",
params = list(spline_cv = FALSE) # Use GCV instead of default
)
#> Computing spline trend with automatic smoothing, GCV
# Polynomial with orthogonal vs raw polynomials
poly_trends <- extract_trends(
AirPassengers,
methods = "poly",
params = list(poly_degree = 2, poly_raw = FALSE) # Orthogonal (default)
)
#> Computing orthogonal polynomial trend with degree = 2
# UCM with different model types
ucm_trends <- extract_trends(
AirPassengers,
methods = "ucm",
params = list(ucm_type = "BSM") # Basic Structural Model with seasonality
)
#> Computing UCM trend: Basic Structural Model with seasonal component
# HP Filter: One-sided (real-time) vs Two-sided (historical)
hp_realtime <- extract_trends(
AirPassengers,
methods = "hp",
params = list(hp_onesided = TRUE) # For nowcasting and real-time analysis
)
#> Computing HP filter (one-sided) with lambda = 129600
# STL with custom parameters via params (both notations work)
stl_custom1 <- extract_trends(
AirPassengers,
methods = "stl",
params = list(s.window = 21, robust = TRUE) # Dot notation
)
#> Computing STL trend with s.window = 21, robust = TRUE
stl_custom2 <- extract_trends(
AirPassengers,
methods = "stl",
params = list(stl_s_window = 21, stl_robust = TRUE) # Underscore notation
)
#> Computing STL trend with s.window = 21, robust = TRUE
# Advanced: fine-tune specific methods
custom_trends <- extract_trends(
AirPassengers,
methods = c("median", "kalman"),
window = 7,
params = list(median_endrule = "constant")
)
#> Computing 7-period median filter with endrule = constant
#> Computing Kalman smoother with measurement noise = auto
