Describes a series over time — separating trend, seasonality, and noise — e.g., is monthly attrition drifting upward once seasonal spikes are removed?
Analyze Time SeriesUnivariatealso known as: Time-series decomposition, Moving averages, Seasonal decomposition
✓ When to use
First look at any time-ordered metric: sales, headcount, complaints, absenteeism.
Separating structural drift (trend) from recurring calendar patterns (seasonality).
Communicating direction and pattern to stakeholders before any forecasting.
✗ When NOT to use
Very short series (< 2 full seasonal cycles) — seasonal estimates are unreliable.
Forecasting demands with accuracy targets — move to ARIMA/ETS after decomposition.
Testing an intervention's effect — interrupted time-series designs, not plain decomposition.
Cross-sectional data — there is no time structure to decompose.
Data requirements
Dependent / outcome variable
One numeric series at regular intervals (daily/monthly/quarterly), ideally 3+ years for monthly seasonality.
Independent / grouping variable
Time itself (and season indicators).
Design
Longitudinal, equally spaced observations; explicit handling of gaps.
Sample size guidance
≥ 24 points for monthly seasonal work; ≥ 50 for stable STL decomposition.
Assumptions
Regular spacing and consistent measurement definitions over time.
Additive pattern (component sizes constant) or multiplicative (proportional to level) — choose to match the data.
Seasonal period known (12 for monthly, 4 for quarterly).
Outliers/level shifts identified — a policy change mid-series is a break, not noise.
Hypotheses
H₀ — For the optional trend test: no monotonic trend (e.g., Mann–Kendall's S = 0; or slope β = 0 in regression on time).
H₁ — A monotonic trend exists.
The concept
Decomposition splits the series as Y = Trend + Seasonal + Remainder (additive) or Y = T × S × R (multiplicative — use when seasonal swings grow with the level). Classical decomposition uses moving averages; STL (Seasonal-Trend decomposition using Loess) is the modern robust default, tolerating outliers and slowly changing seasonality.
Formal trend testing options: regress the (de-seasonalized) series on time for a linear slope, or use the nonparametric Mann–Kendall test with Sen's slope for monotonic trends without linearity assumptions — mindful that autocorrelation inflates both tests' false positives (use corrected variants). The de-seasonalized series is also what you should show management: 'attrition is up 0.2 points per quarter after removing the annual post-appraisal spike'.
Worked example
48 months of attrition rates show spikes each April–May (post-appraisal). STL decomposition isolates a seasonal component of ±0.8 points and a trend rising from 1.9% to 2.6%.
Mann–Kendall on the de-seasonalized series: τ = .41, p < .001; Sen's slope = +0.015 points/month — a real upward drift beyond seasonality.
How to run it
y <- ts(df$attrition, frequency = 12, start = c(2022, 1))
dec <- stl(y, s.window = "periodic")
plot(dec)
# trend test on de-seasonalized series
library(Kendall); library(trend)
adj <- y - dec$time.series[, "seasonal"]
MannKendall(adj)
sens.slope(as.numeric(adj))
import pandas as pd
from statsmodels.tsa.seasonal import STL
import pymannkendall as mk # pip install pymannkendall
s = pd.Series(df["attrition"].values,
index=pd.date_range("2022-01", periods=48, freq="MS"))
res = STL(s, period=12).fit()
res.plot()
adj = s - res.seasonal
print(mk.original_test(adj)) # trend, p, Sen's slope
Define dates: Data → Define date and time (Years, Months).
Analyze → Forecasting → Seasonal Decomposition (choose Additive or Multiplicative); SPSS saves SAF (seasonal factors), SAS (de-seasonalized series), STC (trend-cycle), ERR components.
Plot the saved components: Analyze → Forecasting → Sequence Charts.
Trend test: Regression of SAS on a time index, or nonparametric Mann–Kendall via extensions.
Plot the series; add a moving average: =AVERAGE(OFFSET(...)) or Chart → Trendline → Moving Average (window = season length).
Seasonal indices: average each month's ratio to its centered moving average; de-seasonalize by dividing (multiplicative).
Trend line on de-seasonalized data: =SLOPE(y_range, time_index) with =LINEST for the SE; FORECAST.ETS handles trend+seasonality automatically in recent Excel.
Interpreting the output
Describe each component: trend direction/shape, seasonal amplitude and timing, remainder size.
Quote trend magnitude in real units per period, not just significance.
Note breaks/outliers and their known causes.
Seasonally adjusted values are estimates — say the adjustment method.
Decomposition describes; it does not explain — causal claims need design.
APA-style reporting
STL decomposition of 48 monthly attrition rates revealed a recurring April–May seasonal peak (±0.8 percentage points) and an upward trend from 1.9% to 2.6%. A Mann–Kendall test on the seasonally adjusted series confirmed a significant monotonic increase, τ = .41, p < .001, Sen's slope = 0.015 points per month.
Common mistakes
Reading a raw series' seasonal spike as a trend change.
Additive decomposition on plainly multiplicative data.
Trend tests ignoring autocorrelation.
Too-short series for the claimed seasonality.
Comparing year-on-year without consistent metric definitions.