--- title: "Decomposition and cleaning" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Decomposition and cleaning} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5) ``` ```{r} library(foresightr) ``` ## STL `decompose_stl()` splits a series into trend, seasonal pattern and remainder by LOESS. Its defaults are those of `stats::stl()` and, without `robust`, so are its numbers. ```{r} d <- decompose_stl(log(AirPassengers), seasonal_window = 13) d autoplot(d) ``` The strengths, from 0 to 1, say how much of the variation the trend and the seasonal pattern explain; `seasonal_strength()` computes the latter directly. `robust = TRUE` down-weights outliers. ## Several seasonal periods Daily data often has a weekly and a monthly pattern. `decompose_mstl()` estimates each in turn: ```{r} t <- 0:419 weekly <- c(5, 0, -2, -3, 0, 1, -1) daily <- 100 + 0.05 * t + weekly[t %% 7 + 1] + 8 * sin(2 * pi * t / 30) + 2 * sin(t * 1.7) * cos(t * 0.3) d <- decompose_mstl(daily, periods = c(7, 30)) d$seasonal_strength autoplot(d) ``` The same decomposition serves to forecast: `model_decomposed()` runs any model on the seasonally adjusted series and adds the patterns back. ```{r} model <- model_decomposed(model_drift(), periods = c(7, 30)) f <- forecast_model(model, daily, 14, period = 7) round(f, 1) ``` ## Gaps and outliers ```{r} y <- log(AirPassengers) y[30] <- y[30] + 0.8 # a typing error y[100] <- y[100] - 0.7 # a strike y[61:62] <- NA # months never recorded find_outliers(y) ``` `fill_gaps()` fills the missing values following the seasonal pattern; `clean_series()` also replaces the outliers: ```{r} cleaned <- clean_series(y) round(exp(cbind(dirty = y, clean = cleaned)[c(30, 61, 62, 100), ])) ``` Models require complete series, so cleaning comes first when data has gaps. Whether an outlier should be replaced is a judgement about the data: a strike really happened, and removing it may hide a risk that could happen again.