---
title: "Adjusting Multiple Series"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Adjusting Multiple Series}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  results='hide'
)
```

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.

### Basics

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

```r
library(seasonal)
m <- seas(cbind(fdeaths, mdeaths), x11 = "")
final(m)
```

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.


### Specifying the specs


As in a single series call, we can also use the `list` argument:

```r
seas(cbind(fdeaths, mdeaths), list = list(x11 = ""))
```

It is possible to specify individual specs for each series, by encapsulating
specific spec lists in the `list` argument. In the following, `fdeaths` is
adjusted by X-11 and `mdeaths` by the default SEATS procedure. The length of
list must be equal to number of series.

```r
seas(
  cbind(fdeaths, mdeaths),
  list = list(
    list(x11 = ""),
    list()
  )
)
```

We can even combine these ideas. The following turns off the
AIC test of the regression spec for both series (`regression.aictest = NULL`) and uses X-11 to adjust
`fdeaths` and SEATS to adjust `mdeaths`:

```r
seas(
  cbind(fdeaths, mdeaths),
  regression.aictest = NULL,
  list = list(
    list(x11 = ""),
    list()
  )
)
```

### Specifying multiple series

There are several ways of specifying multiple series. We have already seen how `"mts"`
objects can be used as an input. Alternatively, we can also use a list of single
`"ts"` objects:

```r
seas(list(mdeaths, AirPassengers))
```

This is convenient if series differ in length or frequency. With
the [tsbox](https://www.tsbox.help) package, you can create such lists of time series from any time series object. Let us assume your data is in a data frame:

```r
library(tsbox)
dta <- ts_c(mdeaths = ts_df(mdeaths), AirPassengers = ts_df(AirPassengers))
head(dta)
```

In order to seasonally adjust all series in the data frame, you can run:

```r
seas(ts_tslist(dta))
```

Finally, you can specify the data directly in the list of lists:

```r
seas(
  list = list(
    list(x = mdeaths, x11 = ""),
    list(x = fdeaths)
  )
)
```

### Backend

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:

```r
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:

```r
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 adjustment.

X-13 requires to define a `series.comptype` for individual series. Usually, this
will be set as `series.comptype = "add"`.

The `composite` argument is a list with an X-13 specification that is applied on
the aggregated series. Specification works identical as 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:

```r
m_composite <- seas(
  cbind(mdeaths, fdeaths),
  composite = list(),
  series.comptype = "add"
)
m_composite
```

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

```r
seas(ldeaths)
```

where `ldeaths` is the sum of `mdeaths` and `fdeaths`.

The functions `out()` and `series()` can be used to extract the output or series of the composite adjustment:

```r
out(m_composite)
series(m_composite, "composite.indseasadj"))
```
