Consider the GDP information in global_economy. Plot the
GDP per capita for each country over time. Which country has the highest
GDP per capita? How has this changed over time?
global_economy |>
mutate(GDP_per_capita = GDP / Population) |>
ggplot(aes(x = Year, y = GDP_per_capita, group = Country)) +
geom_line(alpha = 0.5) +
scale_y_log10() +
labs(
title = "GDP per Capita by Country",
x = "Year",
y = "GDP per Capita (log scale)"
)
highest_gdp_per_capita <- global_economy |>
mutate(GDP_per_capita = GDP / Population) |>
as_tibble() |>
group_by(Year) |>
slice_max(GDP_per_capita, n = 1, with_ties = FALSE) |>
select(Year, Country, GDP_per_capita)
highest_gdp_per_capita |>
group_by(Country) |>
summarise(
First_year = min(Year),
Last_year = max(Year),
Years_highest = n(),
.groups = "drop"
) |>
arrange(First_year)
## # A tibble: 6 × 4
## Country First_year Last_year Years_highest
## <fct> <dbl> <dbl> <int>
## 1 United States 1960 1969 8
## 2 Kuwait 1965 1966 2
## 3 Monaco 1970 2016 43
## 4 United Arab Emirates 1976 1977 2
## 5 Liechtenstein 2013 2015 2
## 6 Luxembourg 2017 2017 1
GDP per capita generally increased over time, although the rates of growth differed across countries. The country with the highest GDP per capita also changed over time. The United States was highest during eight early years, while Kuwait was highest in 1965 and 1966. Monaco was the most frequent leader, recording the highest GDP per capita in 43 years between 1970 and 2016, although the United Arab Emirates and Liechtenstein led during some years within that period. Luxembourg had the highest GDP per capita in 2017.
For each series, make a graph of the data. If transforming seems appropriate, apply a transformation and describe its effect.
us_gdp <- global_economy |>
filter(Country == "United States")
us_gdp |>
autoplot(GDP) +
labs(
title = "United States GDP",
x = "Year",
y = "GDP"
)
us_gdp |>
autoplot(log(GDP)) +
labs(
title = "Log-Transformed United States GDP",
x = "Year",
y = "log(GDP)"
)
The original series has a strong upward trend, and its changes become
larger as the level of GDP increases. The logarithmic transformation
compresses the larger values, stabilizes the variation, and makes the
long-term growth pattern more nearly linear.
victorian_bulls <- aus_livestock |>
filter(
State == "Victoria",
Animal == "Bulls, bullocks and steers"
)
victorian_bulls |>
autoplot(Count) +
labs(
title = "Slaughter of Bulls, Bullocks and Steers in Victoria",
x = "Year",
y = "Number slaughtered"
)
lambda_bulls <- victorian_bulls |>
features(Count, features = guerrero) |>
pull(lambda_guerrero)
lambda_bulls
## [1] -0.04461887
victorian_bulls |>
autoplot(box_cox(Count, lambda_bulls)) +
labs(
title = "Box-Cox Transformed Victorian Livestock Slaughter",
subtitle = paste("Lambda =", round(lambda_bulls, 2)),
x = "Year",
y = "Transformed count"
)
The original livestock series contains strong fluctuations, with larger variation occurring when the number slaughtered is higher. The Guerrero method selected a Box-Cox parameter of -0.04. The transformation reduces the influence of the largest peaks and makes the variation more stable over time.
vic_elec |>
autoplot(Demand) +
labs(
title = "Victorian Electricity Demand",
x = "Time",
y = "Demand (MW)"
)
Electricity demand shows strong repeating seasonal patterns and several
large demand peaks. However, the overall level and spread remain
reasonably stable across the observed period. Therefore, a
transformation is not essential for this series, and keeping the data on
its original megawatt scale makes the graph easier to interpret.
aus_production |>
autoplot(Gas) +
labs(
title = "Australian Quarterly Gas Production",
x = "Year",
y = "Gas production"
)
lambda_gas <- aus_production |>
features(Gas, features = guerrero) |>
pull(lambda_guerrero)
lambda_gas
## [1] 0.1095171
aus_production |>
autoplot(box_cox(Gas, lambda_gas)) +
labs(
title = "Box-Cox Transformed Australian Gas Production",
subtitle = paste("Lambda =", round(lambda_gas, 2)),
x = "Year",
y = "Transformed gas production"
)
The original gas production series has a strong upward trend, and the
size of its seasonal fluctuations increases as production rises. The
Guerrero method selected a Box-Cox parameter of 0.11. The transformation
reduces the increasing variation and makes the seasonal fluctuations
more consistent across time.
Why is a Box-Cox transformation unhelpful for the
canadian_gas data?
canadian_gas |>
autoplot(Volume) +
labs(
title = "Monthly Canadian Gas Production",
x = "Year",
y = "Gas production (billions of cubic metres)"
)
A Box-Cox transformation is unhelpful for the Canadian gas data because
the changing variation is not caused only by changes in the level of the
series. The size and shape of the seasonal pattern change over time. A
Box-Cox transformation rescales all observations using one fixed
parameter, so it cannot correct an evolving seasonal pattern. A
decomposition method that permits seasonality to change over time, such
as STL, is more appropriate.
What Box-Cox transformation would you select for your retail data?
set.seed(624)
myseries <- aus_retail |>
filter(`Series ID` == sample(aus_retail$`Series ID`, 1))
myseries |>
distinct(State, Industry, `Series ID`)
## # A tibble: 1 × 3
## State Industry `Series ID`
## <chr> <chr> <chr>
## 1 New South Wales Takeaway food services A3349792X
lambda_retail <- myseries |>
features(Turnover, features = guerrero) |>
pull(lambda_guerrero)
lambda_retail
## [1] 0.002144737
myseries |>
autoplot(Turnover) +
labs(
title = "New South Wales Takeaway Food Services",
x = "Year",
y = "Turnover"
)
myseries |>
autoplot(box_cox(Turnover, lambda_retail)) +
labs(
title = "Box-Cox Transformed Retail Turnover",
subtitle = paste("Lambda =", round(lambda_retail, 2)),
x = "Year",
y = "Transformed turnover"
)
The Guerrero method selected a Box-Cox parameter of 0. Because lambda is
approximately zero, the appropriate transformation is the natural
logarithm of turnover. The log transformation reduces the increasing
seasonal variation and makes the size of the fluctuations more
consistent across time.
Find an appropriate Box-Cox transformation for each series in order to stabilize its variance.
aus_productionlambda_tobacco <- aus_production |>
features(Tobacco, features = guerrero) |>
pull(lambda_guerrero)
lambda_tobacco
## [1] 0.9264636
aus_production |>
autoplot(Tobacco) +
labs(
title = "Australian Tobacco Production",
x = "Year",
y = "Tobacco production"
)
aus_production |>
autoplot(box_cox(Tobacco, lambda_tobacco)) +
labs(
title = "Box-Cox Transformed Tobacco Production",
subtitle = paste("Lambda =", round(lambda_tobacco, 2)),
x = "Year",
y = "Transformed tobacco production"
)
The Guerrero method selected a Box-Cox parameter of 0.93. Because this
value is close to 1, the transformed series is very similar to the
original series. Therefore, little or no transformation is required to
stabilize the variance of Tobacco production.
melsyd_economy <- ansett |>
filter(Airports == "MEL-SYD", Class == "Economy") |>
mutate(Passengers = Passengers / 1000)
lambda_ansett <- melsyd_economy |>
features(Passengers, features = guerrero) |>
pull(lambda_guerrero)
lambda_ansett
## [1] 1.999927
melsyd_economy |>
autoplot(Passengers) +
labs(
title = "Ansett Airlines Economy Class",
subtitle = "Melbourne-Sydney",
x = "Week",
y = "Passengers ('000)"
)
melsyd_economy |>
autoplot(box_cox(Passengers, lambda_ansett)) +
labs(
title = "Box-Cox Transformed Ansett Passengers",
subtitle = paste("Lambda =", round(lambda_ansett, 2)),
x = "Week",
y = "Transformed passengers"
)
The Guerrero method selected a Box-Cox parameter of 2. A value near 2
corresponds to a square-type transformation. This transformation expands
the higher passenger values relative to the lower values and helps
stabilize the variation. The observations with zero passengers remain
unusual because they resulted from the 1989 industrial dispute.
southern_cross <- pedestrian |>
filter(Sensor == "Southern Cross Station")
lambda_pedestrian <- southern_cross |>
features(Count, features = guerrero) |>
pull(lambda_guerrero)
lambda_pedestrian
## [1] -0.2501616
southern_cross |>
autoplot(Count) +
labs(
title = "Pedestrian Counts at Southern Cross Station",
x = "Time",
y = "Pedestrian count"
)
southern_cross |>
autoplot(box_cox(Count, lambda_pedestrian)) +
labs(
title = "Box-Cox Transformed Pedestrian Counts",
subtitle = paste("Lambda =", round(lambda_pedestrian, 2)),
x = "Time",
y = "Transformed pedestrian count"
)
The Guerrero method selected a Box-Cox parameter of -0.25. The negative
lambda applies an inverse-power transformation that strongly compresses
the largest pedestrian counts. This reduces the increasing variation
associated with busy periods and makes the spread more stable over
time.
Consider the last five years of the Gas data from
aus_production.
gas <- tail(aus_production, 5 * 4) |>
select(Gas)
gas |>
autoplot(Gas) +
labs(
title = "Australian Gas Production: Last Five Years",
x = "Year",
y = "Gas production"
)
The series shows clear quarterly seasonal fluctuations, with a similar
pattern of peaks and troughs repeating each year. The overall level
generally increases across the five-year period, indicating an upward
trend-cycle in addition to the seasonality.
gas_decomposition <- gas |>
model(
classical_decomposition(Gas, type = "multiplicative")
)
gas_components <- components(gas_decomposition)
gas_components |>
autoplot() +
labs(
title = "Multiplicative Classical Decomposition of Gas Production"
)
The decomposition supports the original graphical interpretation. The
trend component generally rises over the five-year period, confirming an
upward trend-cycle. The seasonal component shows a stable quarterly
pattern that repeats each year. The remainder contains the irregular
variation that is not explained by the trend-cycle or seasonal
components.
gas_components |>
as_tsibble() |>
autoplot(season_adjust) +
labs(
title = "Seasonally Adjusted Australian Gas Production",
x = "Year",
y = "Seasonally adjusted gas production"
)
gas_middle_outlier <- gas |>
mutate(
Gas = if_else(row_number() == 10, Gas + 300, Gas)
)
middle_outlier_components <- gas_middle_outlier |>
model(
classical_decomposition(Gas, type = "multiplicative")
) |>
components()
middle_outlier_components |>
as_tsibble() |>
autoplot(season_adjust) +
labs(
title = "Seasonally Adjusted Gas Production with a Middle Outlier",
x = "Year",
y = "Seasonally adjusted gas production"
)
Adding 300 to an observation in the middle creates a large spike in the
seasonally adjusted series. The outlier also influences the estimated
trend-cycle and seasonal indices, so its effect is spread to nearby
observations rather than remaining completely isolated. This shows that
classical decomposition is sensitive to unusual observations.
gas_end_outlier <- gas |>
mutate(
Gas = if_else(row_number() == 19, Gas + 300, Gas)
)
end_outlier_components <- gas_end_outlier |>
model(
classical_decomposition(Gas, type = "multiplicative")
) |>
components()
end_outlier_components |>
as_tsibble() |>
autoplot(season_adjust) +
labs(
title = "Seasonally Adjusted Gas Production with an End Outlier",
x = "Year",
y = "Seasonally adjusted gas production"
)
The outlier near the end still creates a large spike in the seasonally
adjusted series. However, its effect differs from the middle outlier
because classical decomposition uses centered moving averages and cannot
estimate the trend-cycle reliably at the endpoints. Therefore, the
influence of the end outlier is less evenly distributed across
surrounding observations, and decomposition estimates near the boundary
are less reliable.
Recall the retail time series selected in Exercise 3.4. Decompose the series using X-11. Does it reveal any outliers or unusual features that were not noticed previously?
retail_x11 <- myseries |>
model(
x11 = X_13ARIMA_SEATS(Turnover ~ x11())
) |>
components()
retail_x11 |>
autoplot() +
labs(
title = "X-11 Decomposition of New South Wales Takeaway Food Services"
)
retail_x11 |>
as_tsibble() |>
as_tibble() |>
mutate(irregular_distance = abs(irregular - 1)) |>
arrange(desc(irregular_distance)) |>
select(Month, Turnover, irregular) |>
slice_head(n = 8)
## # A tibble: 8 × 3
## Month Turnover irregular
## <mth> <dbl> <dbl>
## 1 1993 Mar 122. 0.893
## 2 2002 Jan 229. 1.09
## 3 1983 Dec 89.6 0.914
## 4 1990 Sep 135. 0.914
## 5 1983 Oct 80.1 0.917
## 6 1999 Nov 165. 1.07
## 7 1986 Dec 136. 1.07
## 8 2003 Mar 202. 0.930
The X-11 decomposition separates the long-term trend, seasonal pattern, and irregular movements in retail turnover. The trend generally increases over time, while the seasonal component shows a recurring monthly pattern. The irregular component reveals several isolated observations with unusually large movements that are not explained by the trend or seasonality. These observations are possible outliers that were less obvious in the original time plot.
Figures 3.19 and 3.20 show the decomposition of the number of persons in the Australian civilian labour force from February 1978 to August 1995.
The trend component shows that the civilian labour force generally increased from approximately 6,400 thousand people in 1978 to approximately 9,000 thousand in 1995. The seasonal component is comparatively small, generally ranging from about -100 to 110 thousand, so seasonal movements are only a small proportion of the total labour force. The seasonal pattern also changes over time, particularly for March, August, November, and December. Most remainder values are relatively close to zero, although several exceptionally large negative values appear around 1991–1992.
Yes, the 1991–1992 recession is visible in the estimated components. The trend-cycle temporarily becomes flatter during this period, indicating slower labour-force growth. The recession is especially noticeable in the remainder component, which contains unusually large negative values around 1991 and 1992.