Seasonal Adjustment of Multiple Series

Christoph Sax

seasonal is an easy-to-use and full-featured R-interface to X-13ARIMA-SEATS, the seasonal adjustment software developed by the United States Census Bureau. The latest CRAN version of seasonal makes it much easier to adjust multiple time series.

Photo by Meriç Dağlı

seasonal depends on the x13binary package to access pre-built binaries of X-13ARIMA-SEATS on all platforms and does not require any manual installation. To install both packages:


seas is the core function of the seasonal package. By default, seas calls the automatic procedures of X-13ARIMA-SEATS to perform a seasonal adjustment that works well in most circumstances:


For a more detailed introduction, read our article in the Journal of Statistical Software.

Multiple Series Adjusmtent

In the latest CRAN version 1.8, it is now possible to seasonally adjust multiple series in a single call to seas(). This is done by using the built-in batch mode of X-13. It removes the need for loops or lapply() in such cases and finally brings one missing feature of X-13 to seasonal – the composite spec.

Multiple adjustments can be performed by supplying multiple time series as an "mts" object:

m <- seas(cbind(fdeaths, mdeaths), x11 = "")

This will perform two seasonal adjustments, one for fdeaths and one for mdeaths. X-13 spec-argument combinations can be applied in the usual way, such as x11 = "". Note that if entered that way, they will apply to both series. The vignette on multiple adjustments describes how to specify options for individual series.


X-13 ships with a batch mode that allows multiple adjustments in a single call to X-13. This is now the default in seasonal (multimode = "x13"). Alternatively, X-13 can be called for each series (multimode = "R"). The results should be usually the same, but switching to multimode = "R" may be useful for debugging:

seas(cbind(fdeaths, mdeaths), multimode = "x13")
seas(cbind(fdeaths, mdeaths), multimode = "R")

In general, multimode = "x13" is faster. The following comparison on a MacBook Pro shows a modest speed gain, but bigger differences have been observed on other systems:

many <- rep(list(fdeaths), 100)
system.time(seas(many, multimode = "x13"))
#   user  system elapsed
#  9.415   0.653  10.079
system.time(seas(many, multimode = "R"))
#   user  system elapsed
# 11.130   1.039  12.324

composite spec

Support for the X-13 batch mode makes it finally possible to use the composite spec – the one feature of X-13 that was missing in seasonal. Sometimes, one has to decide whether seasonal adjustment should be performed on a granular level or on an aggregated level. The composite spec helps you to analyze the problem and to compare the direct and the indirect adjustments.

The composite argument is a list with an X-13 specification that is applied on the aggregated series. Specification works identically for other series in seas(), including the application of the defaults. If you provide an empty list, the usual defaults of seas() are used. A minimal composite call looks like this:

  cbind(mdeaths, fdeaths),
  composite = list(),
  series.comptype = "add"

You can verify that the composite refers to the total of mdeaths and fdeaths by running:


where ldeaths is the sum of mdeaths and fdeaths.


Many thanks to Severin Thöni and Matthias Bannert, for demonstrating the benefits of the X-13 batch mode. Also to the ETH KOF, for partially funding this development.

More posts

DevOps Engineer (80-100%)

cynkra team

EFS vs. NFS for RStudio on Kubernetes (AWS): Configuration and considerations

Patrick Schratz

Accessing Google's API via OAuth2

Patrick Schratz

Data Scientist (80-100%)

cynkra team

seasonal 1.9: Accessing composite output

Christoph Sax

Google Season of Docs with R: useR! Information Board

Ben Ubah

Running old versions of TeXlive with tinytex

Kirill Müller

tsbox 0.3.1: extended functionality

Christoph Sax

Celebrating one-year anniversary as RStudio Full Service Certified Partner

Cosima Meyer, Patrick Schratz

Deprecating a pkgdown site served via GitHub Pages

Patrick Schratz, Kirill Müller

gfortran support for R on macOS

Patrick Schratz

Seasonal Adjustment of Multiple Series

Christoph Sax

Dynamic build matrix in GitHub Actions

Kirill Müller

Setting up a load-balanced Jitsi Meet instance

Patrick Schratz

DevOps Expert (f/m/d, 60-100%)

cynkra team

Maintaining multiple identities with Git

Kirill Müller

Relational data models in R

Angel D'az, Kirill Müller

tempdisagg: converting quarterly time series to daily

Christoph Sax

tsbox 0.2: supporting additional time series classes

Christoph Sax

DevOps System Engineer (40-60%)

cynkra team

Introducing dm: easy juggling of tables and relations

Balthasar Sager

tsbox 0.1: class-agnostic time series

Christoph Sax

Data Scientist/Engineer (40-100%)

cynkra team

Time series of the world, unite!

Christoph Sax

Done “Establishing DBI”!?

Kirill Müller

Other blogs