pacman::p_load(
tidyverse, # ggplot, mutate(), cleaning...
tsibble, # as_tsibble()
fable, # model(...), forecast(), tidy(), glance()...
feasts, # ACF(), PACF()
ggtime, # autoplot() for tsibbles
rio, # import()
pander, # pander() markdown tables
patchwork # + and / for ggplots
)Multiplicative Models
Chapter 1: Lesson 5
Learning Outcomes
Decompose time series into trends, seasonal variation, and residuals
- Explain the differences between additive and multiplicative models
- Implement multiplicative decomposition
- Compute the estimators of seasonal variation for a multiplicative model
- Calculate the random component for a multiplicative model
- Compute a seasonally-adjusted time series based on a multiplicative model
Preparation
- Review Sections 1.5.1-1.5.3
Learning Journal Exchange (10 min)
- Review another student’s journal
- What would you add to your learning journal after reading your partner’s?
- What would you recommend your partner add to their learning journal?
- Sign the Learning Journal review sheet for your peer
Packages
Class Activity: Comparing Models in the Textbook Versus R (5 min)
Both the textbook and R use the same model in the additive case:
\[ x_t = m_t + s_t + z_t \]
However, there is a discrepancy in the definitions for the mulitplicative models. The textbook defines the multiplicative model as
\[ x_t = m_t \cdot s_t + z_t \] but R defines the multiplicative model as \[ x_t = m_t \cdot s_t \cdot z_t \] You can investigate R’s definition by executing this command in RStudio.
?classical_decompositionClass Activity: Exploring Simulated Time Series Data (15 min)
So far, you have learned how to estimate a trend using aggregated data (i.e., an annual average) or a moving average. We will compute the seasonal effect and use this to get the random component.
Additive Model
The code hidden below simulates 10 years of a monthly time series with a linear trend and seasonal variation based on an additive model. Because the data are simulated, we know exactly which functions were used to create it, and we can observe what happens when we decompose this function.
Table 1: Simulated Data (Additive Model)
Show the code
# Set random seed for reproducibility
set.seed(20)
# Set parameters & initialize vectors
num_years <- 10
n <- 12 * num_years
sigma <- .75
a <- 0.05
b <- 1
c <- 0.5
trend <- seasonal <- x_t <- rep(0,n)
time_seq <- seq(1,n)
# Generate correlated error terms
w <- rnorm(n + 4, 0, 1)
z = w + lead(w,1) + lead(w,2) + lead(w,3) + lead(w,4)
z = head(z, n) / 2
# Get date
year_seq <- lubridate::year(today()) - num_years + (time_seq - 1) %/% 12
month_seq <- (time_seq - 1) %% 12 + 1
date_seq <- ymd(paste0(year_seq,"-",month_seq,"-01"))
# Get data
for (t in 1:n) {
trend[t] <- a * t + 10
seasonal[t] <- b * sin(t / 12 * 2 * pi * 1) + c * cos(t / 12 * 2 * pi * 3)
x_t[t] <- trend[t] + seasonal[t] + z[t]
}
x_df <- data.frame(x_t = x_t, trend = trend, seasonal = seasonal)
start_year <- lubridate::year(today()) - num_years
start_date <- lubridate::ymd(paste0(start_year,"-01-01"))
# start_date <- lubridate::ymd("1958-01-01")
date_seq <- seq(start_date,
start_date + months(nrow(x_df)-1),
by = "1 months")
x_df_ts <- x_df |>
mutate(
date = date_seq,
month = tsibble::yearmonth(date)
) |>
select(date, month, trend, seasonal, x_t) |>
as_tsibble(index = month)| Date | Month | Trend, $$m_t$$ | Seasonal, $$s_t$$ | Data, $$x_t$$ |
|---|---|---|---|---|
| 2016-01-01 | 2016 Jan | 10.05 | 0.5 | 10.842 |
| 2016-02-01 | 2016 Feb | 10.1 | 0.366 | 10.461 |
| 2016-03-01 | 2016 Mar | 10.15 | 1 | 9.993 |
| 2016-04-01 | 2016 Apr | 10.2 | 1.366 | 9.082 |
| 2016-05-01 | 2016 May | 10.25 | 0.5 | 8.701 |
| 2016-06-01 | 2016 Jun | 10.3 | -0.5 | 7.697 |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2025-11-01 | 2025 Nov | 15.95 | -0.5 | 16.264 |
| 2025-12-01 | 2025 Dec | 16 | 0.5 | 18.165 |
The code above has generated simulated data, where the trend is linear with equation
\[ m_t = \frac{t}{20} \]
and the seasonal effect follows the function
\[ s_t = \sin \left( \frac{t\pi}{6} \right) + \frac{1}{2}\cos\left(\frac{t \pi}{18} \right) \]
Letting \(t\) represent the month number across 10 years, we simulate a time series. Click on the tabs below to compare the actual construction of the time series (using the components generated in the code above) to the decomposition in R.
Here is a plot of the components of the simulated data.
Show the code
trend_plot <- ggplot(x_df_ts, aes(x=month, y=trend)) +
geom_line() +
labs(
title="Plot of Trend",
x="Month",
y="Trend"
) +
theme(plot.title = element_text(hjust = 0.5))
seasonal_plot <- ggplot(x_df_ts, aes(x=month, y=seasonal)) +
geom_line() +
labs(
title="Plot of Seasonal Effect",
x="Month",
y="Seasonal"
) +
theme(plot.title = element_text(hjust = 0.5))
error_plot <- ggplot(x_df_ts, aes(x = month, y = x_t - trend - seasonal)) +
geom_line() +
labs(
title="Plot of Random Error Term",
x="Month",
y="Random"
) +
theme(plot.title = element_text(hjust = 0.5))
x_plot <- ggplot(x_df_ts, aes(x=month, y=x_t)) +
geom_line() +
labs(
title="Plot of Simulated Time Series",
x="Month",
y="x_t"
) +
theme(plot.title = element_text(hjust = 0.5))
x_plot <- x_plot + labs(title = "True (Simulated) Values", x = NULL)
trend_plot <- trend_plot + labs(title = NULL, x = NULL)
seasonal_plot <- seasonal_plot + labs(title = NULL, x = NULL)
error_plot <- error_plot + labs(title = NULL)
x_plot / trend_plot / seasonal_plot / error_plot # uses patchwork
Now, we use R to decompose the time series \(\{x_t\}\).
Show the code
x_decompose <- x_df_ts |>
model(feasts::classical_decomposition(x_t,
type = "add")) |>
components()
autoplot(x_decompose)
Multiplicative Model
We now simulate data and apply R’s multiplicative model. This implies that the error term, \(z_t\), has a mean of 1, rather than 0.
Table 2: Simulated Data (Multiplicative Model)
Show the code
# Set random seed for reproducibility
set.seed(123)
# Set parameters & initialize vectors
num_years <- 10
n <- 12 * num_years
sigma <- .75
a <- 0.03
b <- 1
c <- 0.5
trend <- seasonal <- x_t <- rep(0,n)
time_seq <- seq(1,n)
# Generate correlated error terms
w <- rnorm(n + 4, 0.2, 0.1) # Changed to a mean of 1 and sd of 0.03
z = w + lead(w,1) + lead(w,2) + lead(w,3) + lead(w,4)
z = head(z, n)
# Get date
year_seq <- lubridate::year(today()) - num_years + (time_seq - 1) %/% 12
month_seq <- (time_seq - 1) %% 12 + 1
date_seq <- ymd(paste0(year_seq,"-",month_seq,"-01"))
# Get data
for (t in 1:n) {
trend[t] <- exp(a * t)
seasonal[t] <- exp( b * sin(t / 12 * 2 * pi * 1) + c * cos(t / 12 * 2 * pi * 3) + 1 )
x_t[t] <- trend[t] * seasonal[t] * z[t] # Note R's definition of the mult. model
}
x_df <- data.frame(x_t = x_t, trend = trend, seasonal = seasonal)
start_year <- lubridate::year(today()) - num_years
start_date <- lubridate::ymd(paste0(start_year,"-01-01"))
# start_date <- lubridate::ymd("1958-01-01")
date_seq <- seq(start_date,
start_date + months(nrow(x_df)-1),
by = "1 months")
x_df_ts <- x_df |>
mutate(
date = date_seq,
month = tsibble::yearmonth(date)
) |>
select(date, month, trend, seasonal, x_t) |>
as_tsibble(index = month)| Date | Month | Trend, $$m_t$$ | Seasonal, $$s_t$$ | Data, $$x_t$$ |
|---|---|---|---|---|
| 2016-01-01 | 2016 Jan | 1.03 | 4.482 | 5.065 |
| 2016-02-01 | 2016 Feb | 1.062 | 3.92 | 5.512 |
| 2016-03-01 | 2016 Mar | 1.094 | 7.389 | 11.266 |
| 2016-04-01 | 2016 Apr | 1.127 | 10.655 | 13.348 |
| 2016-05-01 | 2016 May | 1.162 | 4.482 | 5.391 |
| 2016-06-01 | 2016 Jun | 1.197 | 1.649 | 1.93 |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2025-11-01 | 2025 Nov | 35.517 | 1.649 | 39.853 |
| 2025-12-01 | 2025 Dec | 36.598 | 4.482 | 121.366 |
The code above simulated data, where the trend is exponential with equation
\[ m_t = e^{0.03 t} \]
and the seasonal effect follows the function
\[ s_t = \sin \left( \frac{t\pi}{6} \right) + \frac{1}{2}\cos\left(\frac{t \pi}{18} \right) + 1 \]
Letting \(t\) represent the month number across 10 years, we simulate a time series with multiplicative effects. Click on the tabs below to compare the actual construction of the time series (using the components generated in the code above) to the decomposition in R.
Here is a plot of the components of the simulated data.
Show the code
trend_plot <- ggplot(x_df_ts, aes(x=month, y=trend)) +
geom_line() +
labs(
title="Plot of Trend",
x="Month",
y="Trend"
) +
theme(plot.title = element_text(hjust = 0.5))
seasonal_plot <- ggplot(x_df_ts, aes(x=month, y=seasonal)) +
geom_line() +
labs(
title="Plot of Seasonal Effect",
x="Month",
y="Seasonal"
) +
theme(plot.title = element_text(hjust = 0.5))
error_plot <- ggplot(x_df_ts, aes(x = month, y = x_t / trend / seasonal)) +
geom_line() +
labs(
title="Plot of Random Error Term",
x="Month",
y="Random"
) +
theme(plot.title = element_text(hjust = 0.5))
x_plot <- ggplot(x_df_ts, aes(x=month, y=x_t)) +
geom_line() +
labs(
title="Plot of Simulated Time Series",
x="Month",
y="x_t"
) +
theme(plot.title = element_text(hjust = 0.5))
x_plot <- x_plot + labs(title = "True (Simulated) Values", x = NULL)
trend_plot <- trend_plot + labs(title = NULL, x = NULL)
seasonal_plot <- seasonal_plot + labs(title = NULL, x = NULL)
error_plot <- error_plot + labs(title = NULL)
x_plot / trend_plot / seasonal_plot / error_plot 
Now, we use R to decompose the time series \(\{x_t\}\).
Show the code
x_decompose <- x_df_ts |>
model(feasts::classical_decomposition(x_t,
type = "mult")) |>
components()
autoplot(x_decompose)
Which Model Should I Use: Additive or Multiplicative?
Compare the following two time series.

Small Group Activity: Apple’s Quarterly Revenue (45 min)
Please download this file chapter_1_5_handout.xlsx for this activity.
The code below imports and shows a few rows of the quarterly revenues for Apple Inc. (in billions of U.S. dollars).
Show the code
apple_ts <- rio::import("https://byuistats.github.io/timeseries/data/apple_revenue_2026.xlsx") |>
mutate(
dates = as.Date(date), # <-- just coerce/assign directly, no mdy()
year = lubridate::year(dates),
quarter = lubridate::quarter(dates),
value = revenue_billions
) |>
dplyr::select(dates, year, quarter, period_covered, value) |>
arrange(dates) |>
mutate(index = tsibble::yearquarter(dates)) |>
as_tsibble(index = index) |>
rename(revenue = value)
apple_ts |>
select(index, period_covered, revenue) |>
display_partial_table(6,4)| index | period_covered | revenue |
|---|---|---|
| 2005 Q1 | Oct-Dec 2004 | 3.49 |
| 2005 Q2 | Jan-Mar 2005 | 3.243 |
| 2005 Q3 | Apr-Jun 2005 | 3.52 |
| 2005 Q4 | Jul-Sep 2005 | 3.678 |
| 2006 Q1 | Oct-Dec 2005 | 5.749 |
| 2006 Q2 | Jan-Mar 2006 | 4.359 |
| ⋮ | ⋮ | ⋮ |
| 2025 Q4 | Jul-Sep 2025 | 102.466 |
| 2026 Q1 | Oct-Dec 2025 | 143.756 |
| 2026 Q2 | Jan-Mar 2026 | 111.184 |
| 2026 Q3 | Apr-Jun 2026 | 109.417 |
Here are some time plots of the Apple revenue data.
This time plot displays Apple’s quarterly revenue data from 2005 to 2026.
Show the code
# apple_ts |>
# autoplot(.vars = revenue) +
# expand_limits(y = 0) +
# labs(
# x = "Quarter",
# y = "Apple Revenue, Billions $US",
# title = "Apple's Quarterly Revenue, Billions of U.S. Dollars"
# ) +
# theme(plot.title = element_text(hjust = 0.5))
apple_ts |>
autoplot(.vars = revenue) +
aes(color = "Revenue (Billions $US)") +
scale_color_manual(
name = NULL,
values = c("Revenue (Billions $US)" = "black")
) +
expand_limits(y = 0) +
labs(
x = "Quarter",
y = "Apple Revenue, Billions $US",
title = "Apple's Quarterly Revenue, Billions of U.S. Dollars"
) +
theme(
plot.title = element_text(hjust = 0.5),
legend.position = c(0.02, 0.98),
legend.justification = c(0, 1),
legend.background = element_rect(fill = "white", color = "grey70")
)
Here is a plot illustrating the last few years’ of the Apple revenue data:
Show the code
# apple_ts |>
# filter(year >= max(year) - 4) |>
# autoplot(.vars = revenue) +
# expand_limits(y = 0) +
# labs(
# x = "Quarter",
# y = "Apple Revenue, Billions $US",
# title = "Apple's Quarterly Revenue, Billions of U.S. Dollars"
# ) +
# theme(plot.title = element_text(hjust = 0.5))
apple_ts |>
filter(year >= max(year) - 4) |>
autoplot(.vars = revenue) +
aes(color = "Revenue (Billions $US)") +
scale_color_manual(
name = NULL,
values = c("Revenue (Billions $US)" = "black")
) +
expand_limits(y = 0) +
labs(
x = "Quarter",
y = "Apple Revenue, Billions $US",
title = "Apple's Quarterly Revenue, Billions of U.S. Dollars"
) +
theme(
plot.title = element_text(hjust = 0.5),
legend.position = c(0.02, 0.98),
legend.justification = c(0, 1),
legend.background = element_rect(fill = "white", color = "grey70")
)
We want to find the seasonally adjusted series for a multiplicative model. This is a multi-step process.
Centered Moving Average
First, we compute the centered moving average, \(\hat m_t\).
To emphasize the computation of the centered moving average, the observed data values that were used to find \(\hat m_t\) for the fourth quarter of 2005 are shown in green in the table below.
Estimated Quarterly Multiplicative Effect
Next, the centered moving average, \(\hat m_t\), is used to compute the quarterly multiplictive effect, \(\hat s_t\):
\[ \hat s_t = \dfrac{ x_t }{ \hat m_t } \]
Table 3: Computation of the Centered Moving Average, \(\hat m_t\), and the Estimated Quarterly Multiplicative Effect, \(\hat s_t\)
| quarter | Revenue $$x_t$$ | $$ \hat m_t $$ | $$ \hat s_t $$ |
|---|---|---|---|
| 2005 Q1 | 3.49 | NA | NA |
| 2005 Q2 | 3.243 | NA | NA |
| 2005 Q3 | 3.52 | 3.765 | 0.935 |
| 2005 Q4 | 3.678 | 4.187 | 0.878 |
| 2006 Q1 | 5.749 | ______ | ______ |
| 2006 Q2 | 4.359 | ______ | ______ |
| 2006 Q3 | 4.37 | ______ | ______ |
| 2006 Q4 | 4.837 | ______ | ______ |
| 2007 Q1 | 7.123 | ______ | ______ |
| 2007 Q2 | 5.286 | ______ | ______ |
| 2007 Q3 | 5.563 | ______ | ______ |
| 2007 Q4 | 6.606 | ______ | ______ |
| 2008 Q1 | 10.43 | ______ | ______ |
| 2008 Q2 | 7.98 | ______ | ______ |
| ⋮ | ⋮ | ⋮ | ⋮ |
| 2025 Q3 | 94.036 | ______ | ______ |
| 2025 Q4 | 102.466 | ______ | ______ |
| 2026 Q1 | 143.756 | ______ | ______ |
| 2026 Q2 | 111.184 | ______ | ______ |
| 2026 Q3 | 109.417 | ______ | ______ |
Seasonally Adjusted Factors
Next, we need to compute the mean (across years) of \(\hat s_t\) by quarter. To help us calculate this, it can be convenient to organize the values of \(\hat s_t\) in a table, where the rows give the year and the columns give the quarter.
The overall mean of these means will be reasonably close to, but not exactly one. We adjust these values by dividing the quarterly means by the overall mean.
Table 4: Computation of the Seasonally Adjusted Factors, \(\bar s_t\)
| Year | Q1 | Q2 | Q3 | Q4 |
|---|---|---|---|---|
| 2005 | NA | NA | 0.935 | 0.878 |
| 2006 | ______ | ______ | ______ | ______ |
| 2007 | ______ | ______ | ______ | ______ |
| 2008 | ______ | ______ | ______ | ______ |
| 2009 | ______ | ______ | ______ | ______ |
| 2010 | 1.159 | 0.883 | 0.888 | 0.994 |
| 2011 | 1.139 | 0.946 | 0.968 | 0.837 |
| 2012 | 1.273 | 1.027 | 0.872 | 0.862 |
| 2013 | 1.288 | 1.025 | 0.819 | 0.856 |
| 2014 | 1.301 | 1.012 | 0.783 | 0.818 |
| 2015 | 1.367 | 1.013 | 0.847 | 0.891 |
| 2016 | 1.355 | 0.928 | 0.781 | 0.855 |
| 2017 | 1.412 | 0.935 | 0.776 | 0.864 |
| 2018 | 1.405 | 0.939 | 0.808 | 0.968 |
| 2019 | 1.303 | 0.894 | 0.816 | 0.956 |
| 2020 | 1.356 | 0.851 | 0.84 | 0.835 |
| 2021 | 1.326 | 1.005 | 0.875 | 0.872 |
| 2022 | 1.282 | 0.995 | 0.849 | 0.933 |
| 2023 | 1.219 | 0.989 | 0.851 | 0.933 |
| 2024 | 1.247 | 0.935 | 0.872 | 0.954 |
| 2025 | 1.229 | 0.925 | 0.883 | 0.924 |
| 2026 | 1.252 | NA | NA | NA |
| Mean | 1.284 | ______ | ______ | ______ |
| $$ \bar s_t $$ | 1.286 | $$~$$ ______ | $$~$$ ______ | $$~$$ ______ |
Random Component and the Seasonally Adjusted Time Series
Using R’s definition of the multiplicative model, \[ x_t = m_t \cdot s_t \cdot z_t \] we calculate the random component by dividing the values in the time series by the product of the trend and the seasonally adjusted factor:
\[ \text{random component} = \dfrac{ x_t }{ \hat m_t \cdot \bar s_t } \]
The seasonally adjusted series is computed by dividing the respective observed values by \(\bar s_t\):
\[ \text{seasonally adjusted series} = \dfrac{ x_t }{ \bar s_t } \]
Use these equations to calculate the values missing from the table below. The adjusted seasonal effect \(\bar s_t\) (s_bar) was computed in the last row of the previous table.
Table 5: Computation of the Random Component and the Seasonally Adjusted Time Series
| Quarter | Revenue $$x_t$$ | $$ \hat m_t $$ | $$ \hat s_t $$ | $$ \bar s_t $$ | Random | Seasonally Adjusted $$x_t$$ |
|---|---|---|---|---|---|---|
| 2005 Q1 | 3.49 | NA | NA | 1.286 | NA | 2.713 |
| 2005 Q2 | 3.243 | NA | NA | ______ | NA | 3.428 |
| 2005 Q3 | 3.52 | 3.765 | 0.935 | ______ | 1.098 | 4.136 |
| 2005 Q4 | 3.678 | 4.187 | 0.878 | ______ | 0.958 | 4.013 |
| 2006 Q1 | 5.749 | ______ | ______ | ______ | ______ | ______ |
| 2006 Q2 | 4.359 | ______ | ______ | ______ | ______ | ______ |
| 2006 Q3 | 4.37 | ______ | ______ | ______ | ______ | ______ |
| 2006 Q4 | 4.837 | ______ | ______ | ______ | ______ | ______ |
| 2007 Q1 | 7.123 | ______ | ______ | ______ | ______ | ______ |
| 2007 Q2 | 5.286 | ______ | ______ | ______ | ______ | ______ |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2025 Q4 | 102.466 | ______ | ______ | ______ | ______ | ______ |
| 2026 Q1 | 143.756 | ______ | ______ | ______ | ______ | ______ |
| 2026 Q2 | 111.184 | ______ | ______ | ______ | ______ | ______ |
| 2026 Q3 | 109.417 | ______ | ______ | ______ | ______ | ______ |
Class Activity: Computing the Multiplicative Decomposition in R (5 min)
The R code below calculates the decomposition, including the seasonally adjusted time series, beginning with the tsibble apple_ts.
Table 6: First Few Rows of the Decomposition of the Apple Revenue Time Series
Show the code
apple_decompose <- apple_ts |>
model(feasts::classical_decomposition(revenue,
type = "mult")) |>
components()
apple_decompose |>
head(8) |>
display_table()| .model | index | revenue | trend | seasonal | random | season_adjust |
|---|---|---|---|---|---|---|
| feasts::classical_decomposition(revenue, type = "mult") | 2005 Q1 | 3.490 | NA | 1.2863724 | NA | 2.713056 |
| feasts::classical_decomposition(revenue, type = "mult") | 2005 Q2 | 3.243 | NA | 0.9459724 | NA | 3.428218 |
| feasts::classical_decomposition(revenue, type = "mult") | 2005 Q3 | 3.520 | 3.765125 | 0.8511409 | 1.0984033 | 4.135626 |
| feasts::classical_decomposition(revenue, type = "mult") | 2005 Q4 | 3.678 | 4.187000 | 0.9165143 | 0.9584501 | 4.013031 |
| feasts::classical_decomposition(revenue, type = "mult") | 2006 Q1 | 5.749 | 4.432750 | 1.2863724 | 1.0082131 | 4.469157 |
| feasts::classical_decomposition(revenue, type = "mult") | 2006 Q2 | 4.359 | 4.683875 | 0.9459724 | 0.9837916 | 4.607957 |
| feasts::classical_decomposition(revenue, type = "mult") | 2006 Q3 | 4.370 | 5.000500 | 0.8511409 | 1.0267544 | 5.134285 |
| feasts::classical_decomposition(revenue, type = "mult") | 2006 Q4 | 4.837 | 5.288125 | 0.9165143 | 0.9980105 | 5.277604 |
The figure below illustrates the original time series (in black), the centered moving average \(\hat m_t\) (in blue), and the seasonally adjusted series (in red).
From 2005 to 2026:
Show the code
apple_decompose |>
ggplot(aes(x = index)) +
geom_line(aes(y = revenue, color = "Revenue")) +
geom_line(aes(y = season_adjust, color = "Seasonally Adjusted")) +
geom_line(aes(y = trend, color = "Trend")) +
expand_limits(y = 0) +
scale_color_manual(
name = NULL,
values = c(
"Revenue" = "black",
"Seasonally Adjusted" = "#D55E00",
"Trend" = "#0072B2"
)
) +
labs(
x = "Quarter",
y = "Quarterly Revenue, Billions",
title = "Apple Inc. Quarterly Revenue (in Billions of U.S. Dollars)"
) +
theme(
plot.title = element_text(hjust = 0.5),
legend.position = c(0.02, 0.98),
legend.justification = c(0, 1),
legend.background = element_rect(fill = "white", color = "grey70")
)
From 2022 to 2026:
Show the code
apple_decompose |>
filter(year(index) >= max(year(index)) - 4) |>
ggplot(aes(x = index)) +
geom_line(aes(y = revenue, color = "Revenue")) +
geom_line(aes(y = season_adjust, color = "Seasonally Adjusted")) +
geom_line(aes(y = trend, color = "Trend")) +
expand_limits(y = 0) +
scale_color_manual(
name = NULL,
values = c(
"Revenue" = "black",
"Seasonally Adjusted" = "#D55E00",
"Trend" = "#0072B2"
)
) +
labs(
x = "Quarter",
y = "Quarterly Revenue, Billions",
title = "Apple Inc. Quarterly Revenue (in Billions of U.S. Dollars)"
) +
theme(
plot.title = element_text(hjust = 0.5),
legend.position = c(0.02, 0.98),
legend.justification = c(0, 1),
legend.background = element_rect(fill = "white", color = "grey70")
)
The following figures compare the decomposition obtained for the Apple revenue data based on the multiplicative and additive models.
Decomposition based on a multiplicative model:
Show the code
autoplot(apple_decompose)
Decomposition based on an additive model:
Show the code
apple_ts |>
model(feasts::classical_decomposition(revenue,
type = "add")) |>
components() |>
autoplot()
Homework Preview (5 min)
- Review upcoming homework assignment
- Clarify questions