roll_series: Rolling aggregations for time series objects

View source: R/roll_series.R

roll_seriesR Documentation

Rolling aggregations for time series objects

Description

Compute rolling and year-to-date aggregations of a time series. Unlike extract_trends(), which estimates a trend in the units of the series, these are aggregations: a 12-month rolling sum is a 12-month total, not a level estimate. The two families are kept separate for that reason, so rolling results are not accepted by detrend_series().

Usage

roll_series(
  ts_data,
  stats = "sum",
  window = NULL,
  align = "right",
  percent = FALSE,
  na_rm = FALSE,
  .quiet = FALSE
)

Arguments

ts_data

A time series object (ts, xts, or zoo) or any object convertible via tsbox.

stats

Character vector of rolling statistics. Options: "sum" (rolling total of flows), "chain" (compound accumulation of rates, prod(1 + r) - 1), "change" (change of a level over window periods, x[t] / x[t - window] - 1), "mean", "sd", "min", "max". Default is "sum".

window

Window length in periods, or the lag for "change". If NULL, defaults to the series frequency (12 for monthly, 4 for quarterly). A numeric vector runs the statistic once per window value. Alternatively, the string "ytd" computes an expanding year-to-date accumulation that resets each January (or Q1), and "all" an expanding accumulation from the first observation. Numeric and character windows cannot be mixed in one call, and "change" needs a numeric window.

align

Alignment of the window relative to the output position: "right" (default, causal — uses the current and preceding observations), "center", or "left". Right alignment is the convention for accumulated economic indicators. Ignored by "change" and by the expanding windows "ytd" and "all". An even window has no exact centre; see Details for how each statistic handles that.

percent

Only used by stats = "chain" and stats = "change". For "chain", if FALSE (default), rates are assumed to be decimals (0.005 for 0.5%). If TRUE, rates are assumed to be percentages (0.5 for 0.5%) and the result is returned in percent. For "change", TRUE returns the change in percent instead of as a decimal.

na_rm

If TRUE, missing values are ignored within each window. The default FALSE propagates NA, so an incomplete window yields NA. A window holding no observed values yields NA either way, as does a window holding one value for "sd". For even centered means, observed weights are renormalized under na_rm = TRUE; boundary padding is kept. "change" ignores it: a missing value at either end yields NA.

.quiet

If TRUE, suppress informational messages.

Details

stats = "sum" and stats = "chain" answer the same question for different kinds of series. For a flow measured in levels (units sold, jobs created), the 12-month accumulation is the sum. For a series that is already a rate of change (monthly inflation, monthly returns), summing is only an approximation; the correct accumulation compounds the rates:

(1 + r_1)(1 + r_2)\cdots(1 + r_k) - 1

stats = "change" goes the other way, from a level (an index, a price, real income) to its rate of change over window periods. Chaining the one-period changes over k periods gives back the k-period change. The lag counts periods on the calendar grid for monthly, quarterly and annual series, and observations for daily and weekly series.

Note that a rolling sum is proportional to the simple moving average available through extract_trends(): roll_series(x, "sum", window = k) equals k times extract_trends(x, "ma", window = k, align = "right"). The rolling version is the one to reach for when the accumulated quantity is itself the number of interest. The two part company for an even window under align = "center", where the moving average is weighted and the sum is not.

An even window centred on an observation has one more period on one side than the other. "mean" resolves this the way the ma trend method does, with the 2xN filter that puts half weight on the two endpoints, so roll_series(x, "mean", window = k, align = "center") matches extract_trends(x, "ma", window = k, align = "center"). The other statistics have no such correction and use a window with one extra period after the anchor.

Value

If a single statistic and a single window are requested, a ts object. Otherwise a named list of ts objects with names of the form ⁠{stat}_{window}⁠ (e.g. sum_12, chain_ytd, change_12).

See Also

augment_rolling() for the data frame interface, extract_trends() for trend estimation.

Examples

# 12-month rolling sum of vehicle production
prod_ts <- df_to_ts(vehicles, value_col = "production", frequency = 12)
roll_series(prod_ts, "sum", window = 12)

# Accumulated growth over 12 months, from monthly rates in percent
ibc_ts <- df_to_ts(ibcbr, value_col = "index", frequency = 12)
rates <- roll_series(ibc_ts, "change", window = 1, percent = TRUE)
roll_series(rates, "chain", window = 12, percent = TRUE)

# Year-to-date accumulation, resetting each January
roll_series(rates, "chain", window = "ytd", percent = TRUE)

# Cumulative growth since the start of the series
roll_series(rates, "chain", window = "all", percent = TRUE)

# 12-month change of the index, in percent
roll_series(ibc_ts, "change", window = 12, percent = TRUE)

# Several statistics and windows at once
roll_series(prod_ts, stats = c("sum", "sd"), window = c(3, 12))


trendseries documentation built on Oct. 1, 2026, 5:10 p.m.