# Trend Extraction Methods

    library(trendseries)

This vignette is a catalogue of every trend-extraction method in `trendseries`: which family it belongs to, when to reach for it, and which parameters it accepts. For worked examples of specific families, see the companion Moving Averages and Econometric Filters vignettes. To split a series into trend, seasonal, and remainder components instead of extracting a single smooth trend, see Decomposing Series.

# The two interfaces

Every method is reachable through two functions that share the same engine and the same parameters:

- `augment_trends()` — pipe-friendly. Takes a `data.frame`/`tibble`, adds `trend_{method}` columns, and supports grouped series via `group_cols`.
- `extract_trends()` — takes a `ts`/`xts`/`zoo` object and returns `ts` objects (a single `ts` for one method, a named list for several).

    # Data-frame interface: adds a trend_stl column
    head(augment_trends(ibcbr, value_col = "index", methods = "stl"))
    #> # A tibble: 6 × 3
    #>   date       index trend_stl
    #>   <date>     <dbl>     <dbl>
    #> 1 2003-01-01  67.1      70.2
    #> 2 2003-02-01  68.8      70.2
    #> 3 2003-03-01  72.2      70.3
    #> 4 2003-04-01  71.3      70.4
    #> 5 2003-05-01  70.0      70.5
    #> 6 2003-06-01  68.8      70.7

    # Time-series interface: returns a ts object
    hp_trend <- extract_trends(AirPassengers, methods = "hp")
    class(hp_trend)
    #> [1] "ts"

Pass several methods at once to compare them:

    trends <- augment_trends(
      ibcbr,
      value_col = "index",
      methods = c("hp", "stl", "henderson")
    )
    head(trends)
    #> # A tibble: 6 × 5
    #>   date       index trend_hp trend_stl trend_henderson
    #>   <date>     <dbl>    <dbl>     <dbl>           <dbl>
    #> 1 2003-01-01  67.1     69.0      70.2              NA
    #> 2 2003-02-01  68.8     69.3      70.2              NA
    #> 3 2003-03-01  72.2     69.6      70.3              NA
    #> 4 2003-04-01  71.3     69.9      70.4              NA
    #> 5 2003-05-01  70.0     70.2      70.5              NA
    #> 6 2003-06-01  68.8     70.5      70.7              NA

# The unified parameter system

Rather than exposing every method’s idiosyncratic arguments, `trendseries` routes a small set of generic parameters to whichever method-specific option they correspond to. Sensible, frequency-aware defaults mean you rarely need to set them.

Parameter | Applies to | Meaning
--- | --- | ---
`window` | moving-average methods (`ma`, `wma`, `triangular`, `ewma`, `median`, `gaussian`, `stl`) | Number of observations in the smoothing window.
`smoothing` | `hp`, `loess`, `spline`, `ewma`, `kernel`, `kalman` | Amount of smoothing (interpretation varies by method).
`band` | bandpass filters (`bk`, `cf`) | `c(low, high)` cycle periods to keep.
`align` | `ma`, `wma`, `triangular`, `gaussian` | `"center"` (default), `"right"` (causal), or `"left"`.
`params` | all | A named list for any remaining method-specific options.

    # A wider HP smoothing and a 12-month moving average, in one call
    augment_trends(
      ibcbr,
      value_col = "index",
      methods = c("hp", "ma"),
      smoothing = 1600,
      window = 12
    ) |>
      head()
    #> # A tibble: 6 × 4
    #>   date       index trend_hp trend_ma
    #>   <date>     <dbl>    <dbl>    <dbl>
    #> 1 2003-01-01  67.1     68.9     NA
    #> 2 2003-02-01  68.8     69.2     NA
    #> 3 2003-03-01  72.2     69.5     NA
    #> 4 2003-04-01  71.3     69.9     NA
    #> 5 2003-05-01  70.0     70.2     NA
    #> 6 2003-06-01  68.8     70.5     70.6

Frequency-aware defaults adapt to the data: for monthly series the HP smoothing parameter defaults to `lambda = 14400` and the moving-average window to 12; for quarterly series, `lambda = 1600` and a window of 4 (Ravn & Uhlig, 2002).

# Method catalogue

`trendseries` ships 20 trend methods across four families.

Method | Category | Description | Typical use
--- | --- | --- | ---
`hp` | econometric | Hodrick-Prescott filter | General-purpose business-cycle trend
`hamilton` | econometric | Hamilton regression filter | HP alternative without spurious cycles
`bn` | econometric | Beveridge-Nelson decomposition | Permanent/transitory split
`ucm` | econometric | Unobserved components model | Model-based, stochastic trend
`bk` | bandpass | Baxter-King bandpass filter | Isolating a cycle frequency band
`cf` | bandpass | Christiano-Fitzgerald bandpass filter | Asymmetric bandpass, uses endpoints
`ma` | moving average | Simple moving average | Quick, intuitive smoothing
`wma` | moving average | Weighted moving average | Smoothing with custom weights
`ewma` | moving average | Exponentially weighted moving average | Recent-weighted, real-time smoothing
`triangular` | moving average | Triangular moving average | Smoother than a simple MA
`median` | moving average | Median filter | Robust to outliers/spikes
`gaussian` | moving average | Gaussian-weighted moving average | Smooth, bell-weighted average
`spencer` | moving average | Spencer’s 15-term moving average | Classic actuarial graduation
`henderson` | moving average | Henderson moving average | Trend term inside X-11 seasonal adj.
`stl` | smoothing | Seasonal-trend decomposition via Loess | Trend from strongly seasonal data
`loess` | smoothing | Local polynomial regression | Flexible non-parametric trend
`spline` | smoothing | Smoothing splines | Smooth curve with automatic penalty
`poly` | smoothing | Polynomial trends | Simple global trend shape
`kernel` | smoothing | Kernel smoother | Non-parametric, bandwidth-controlled
`kalman` | smoothing | Kalman filter/smoother | Adaptive trend for noisy series

## Moving averages

Moving-average methods replace each point with a (possibly weighted) average of its neighbours. They are fast, transparent, and a good default for exploratory work. Control the smoothing through `window` (and `align` for causal vs. centred variants). `ma`, `median`, and `henderson` also accept a vector of windows, returning one trend per window.

    augment_trends(
      ibcbr,
      value_col = "index",
      methods = "henderson",
      window = c(13, 23)
    ) |>
      head()
    #> # A tibble: 6 × 4
    #>   date       index trend_henderson_13 trend_henderson_23
    #>   <date>     <dbl>              <dbl>              <dbl>
    #> 1 2003-01-01  67.1                 NA                 NA
    #> 2 2003-02-01  68.8                 NA                 NA
    #> 3 2003-03-01  72.2                 NA                 NA
    #> 4 2003-04-01  71.3                 NA                 NA
    #> 5 2003-05-01  70.0                 NA                 NA
    #> 6 2003-06-01  68.8                 NA                 NA

See Moving Averages for the full treatment.

## Smoothing methods

Smoothing methods fit a flexible curve to the data. `stl` and `loess` are locally adaptive; `spline` and `kernel` trade off fit against smoothness through a penalty/bandwidth; `poly` imposes a single global shape. The `smoothing` parameter tunes how aggressively they smooth.

    loess_trend <- extract_trends(AirPassengers, methods = "loess", smoothing = 0.3)
    plot(AirPassengers, col = "grey60", ylab = "Air passengers")
    lines(loess_trend, col = "#C53030", lwd = 2)

## Econometric filters

These are the workhorses of applied macroeconomics. The Hodrick-Prescott filter (`hp`) is the most widely used; `hamilton` is a regression-based alternative that avoids HP’s well-known spurious-cycle artefacts; `bn` and `ucm` are model-based decompositions into permanent and transitory parts.

    augment_trends(
      gdp_construction,
      value_col = "index",
      methods = c("hp", "hamilton")
    ) |>
      head()
    #> # A tibble: 6 × 4
    #>   date       index trend_hp trend_hamilton
    #>   <date>     <dbl>    <dbl>          <dbl>
    #> 1 1995-01-01 100       101.             NA
    #> 2 1995-04-01 100       101.             NA
    #> 3 1995-07-01 100       102.             NA
    #> 4 1995-10-01 100       103.             NA
    #> 5 1996-01-01  97.8     103.             NA
    #> 6 1996-04-01 101.      104.             NA

The HP filter has a one-sided (real-time) variant for nowcasting, where future observations must not influence the current estimate:

    extract_trends(
      AirPassengers,
      methods = "hp",
      params = list(hp_onesided = TRUE)
    ) |>
      head()
    #>           Jan      Feb      Mar      Apr      May      Jun
    #> 1949 111.9999 118.0001 130.6667 132.5000 128.1995 133.1425

See Econometric Filters for details.

## Bandpass filters

Bandpass filters (`bk`, `cf`) keep only the fluctuations whose periodicity falls inside a chosen band, removing both the long-run trend and high-frequency noise. Specify the band with `band = c(low, high)` in periods (quarters for quarterly data):

    extract_trends(
      AirPassengers,
      methods = "cf",
      band = c(18, 96)
    ) |>
      head()
    #>           Jan      Feb      Mar      Apr      May      Jun
    #> 1949 129.2137 124.0873 127.3082 114.4644  98.0897 105.6196

# Decomposition vs. trend extraction

The methods above estimate a single smooth trend. When you instead want to split a series into trend + seasonal + remainder, use `decompose_series()`, which offers five methods of its own:

Method | Engine | Notes
--- | --- | ---
`stl` | `stats::stl()` | Loess-based, robust option available.
`regression` | OLS | Polynomial trend + seasonal dummies.
`classic` | `stats::decompose()` | Classical moving-average; additive or multiplicative.
`bsm` | `stats::StructTS()` | State-space model; components for every point.
`seats` | X-13ARIMA-SEATS | Requires the optional `seasonal` package.

    decompose_series(gdp_construction, value_col = "index", methods = "stl") |>
      head()
    #> # A tibble: 6 × 5
    #>   date       index trend_stl seasonal_stl remainder_stl
    #>   <date>     <dbl>     <dbl>        <dbl>         <dbl>
    #> 1 1995-01-01 100       102.         -4.37         1.93
    #> 2 1995-04-01 100       101.         -1.62         0.476
    #> 3 1995-07-01 100       100.          4.44        -4.62
    #> 4 1995-10-01 100        99.4         1.55        -0.946
    #> 5 1996-01-01  97.8     101.         -4.37         1.42
    #> 6 1996-04-01 101.      102.         -1.62         0.613

The dedicated Decomposing Series vignette covers these in depth.

# References

Ravn, M. O., & Uhlig, H. (2002). On adjusting the Hodrick-Prescott filter for the frequency of observations. The Review of Economics and Statistics, 84(2), 371–376.