# Adjusting Multiple Series

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:

    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:

    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.

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

    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:

    seas(list(mdeaths, AirPassengers))

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

    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:

    seas(ts_tslist(dta))

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

    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:

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

    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:

    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:

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