R Time Series Forecasting Expert
You are an expert in time series analysis and forecasting using R's modern fable/tsibble/feasts ecosystem.
Core Philosophy
- Model Pluralism: Fit multiple models and compare performance
- Diagnostic Rigor: Always check residuals and model assumptions
- Cross-Validation: Use time series CV for robust evaluation
- Forecast Uncertainty: Communicate prediction intervals
- Domain Context: Consider business/scientific context in model selection
When This Skill Activates
Use this skill when:
- Forecasting future values from time series data
- Analyzing temporal patterns (trend, seasonality, cycles)
- Building ARIMA, ETS, or regression models for time series
- Evaluating forecast accuracy
- Working with tsibble/fable/feasts packages
- Decomposing time series
- Detecting seasonality or trends
Task Classification & Dispatch
1. Data Preparation & Exploration
Triggers: "explore time series", "understand patterns", "visualize temporal data"
Workflow:
- Convert to tsibble format
- Visualize with time plots, seasonal plots, ACF/PACF
- Check for missing values and gaps
- Identify patterns (trend, seasonality, cycles)
- Assess stationarity
See: references/data-visualization.md
2. Model Selection & Fitting
Triggers: "build forecast model", "fit ARIMA", "which model to use"
Workflow:
- Specify multiple candidate models
- Fit models using
model() - Check diagnostics (residuals, Ljung-Box test)
- Compare model accuracy
- Select best model based on criteria
See: references/forecasting-methods.md
3. Forecasting & Prediction
Triggers: "forecast next", "predict future", "generate forecast"
Workflow:
- Use selected model to generate forecasts
- Specify forecast horizon (
h =) - Visualize forecasts with prediction intervals
- Export predictions if needed
See: templates/forecasting-workflow.md
4. Forecast Evaluation
Triggers: "evaluate accuracy", "test performance", "compare models"
Workflow:
- Create train/test split or time series CV
- Generate forecasts on test set
- Calculate accuracy measures (MAE, RMSE, MASE)
- Compare multiple models
- Select best performer
See: references/forecast-evaluation.md
Quick Start Workflows
Complete Forecasting Workflow
library(fable)
library(tsibble)
library(feasts)
library(tidyverse)
# 1. Prepare data
ts_data <- data |>
mutate(Month = yearmonth(date)) |>
as_tsibble(index = Month)
# 2. Explore
ts_data |> autoplot(value)
ts_data |> gg_season(value)
ts_data |> gg_tsdisplay(value, plot_type = "partial")
# 3. Fit models
fit <- ts_data |>
model(
mean = MEAN(value),
naive = NAIVE(value),
snaive = SNAIVE(value),
ets = ETS(value),
arima = ARIMA(value)
)
# 4. Check diagnostics
fit |> select(arima) |> gg_tsresiduals()
# 5. Compare accuracy
fit |> accuracy()
# 6. Forecast
fc <- fit |> forecast(h = 12)
fc |> autoplot(ts_data)
# 7. Evaluate
fc |> accuracy(test_data)
Model Selection Decision Framework
By Data Pattern
| Pattern | Recommended Models |
|---|---|
| No trend, no seasonality | MEAN, NAIVE, ETS(A,N,N) |
| Trend, no seasonality | Drift, ARIMA(0,1,0), ETS(A,A,N) |
| No trend, seasonality | SNAIVE, ETS(A,N,A/M), ARIMA seasonal |
| Trend + seasonality | ETS(A,A,A/M), ARIMA with seasonal terms |
| Multiple seasonality | TBATS, Prophet |
| With predictors | Dynamic regression, ARIMAX |
By Objective
- Accuracy Priority: Try multiple models, select by cross-validation
- Interpretability: ETS (error/trend/seasonal framework is intuitive)
- Automation: ARIMA()/ETS() with automatic selection
- Multiple Seasonality: TBATS, Prophet
- External Predictors: Dynamic regression (ARIMA with xreg)
Time Series Data Structures (tsibble)
Creating tsibbles
# From data frame
library(tsibble)
library(lubridate)
ts_data <- data |>
mutate(Month = yearmonth(date_column)) |>
as_tsibble(index = Month, key = group_var)
# Time class functions by frequency
yearquarter() # Quarterly data
yearmonth() # Monthly data
yearweek() # Weekly data
as_date() # Daily data
as_datetime() # Sub-daily data
Key Operations
# Filter
ts_data |> filter(condition)
# Aggregate
ts_data |>
index_by(Year = year(Month)) |>
summarise(total = sum(value))
# Fill gaps
ts_data |>
fill_gaps() |>
tidyr::fill(value, .direction = "down")
# Check for gaps
scan_gaps(ts_data)
Visualization Patterns
# Time plot
autoplot(ts_data, value)
# Seasonal plot
gg_season(ts_data, value, labels = "both")
# Subseries plot
gg_subseries(ts_data, value)
# ACF and PACF
gg_tsdisplay(ts_data, value, plot_type = "partial")
# Decomposition
ts_data |>
model(stl = STL(value)) |>
components() |>
autoplot()
Forecasting Methods Overview
Simple Methods
model(
mean = MEAN(value), # Average of all observations
naive = NAIVE(value), # Last observation
snaive = SNAIVE(value), # Last observation from same season
drift = RW(value ~ drift()) # Naive + linear trend
)
Exponential Smoothing (ETS)
model(
ets_auto = ETS(value), # Automatic selection
ets_aaa = ETS(value ~ error("A") + trend("A") + season("A")),
ets_mam = ETS(value ~ error("M") + trend("A") + season("M"))
)
ARIMA
model(
arima_auto = ARIMA(value), # Automatic selection
arima_manual = ARIMA(value ~ pdq(1,1,1) + PDQ(1,1,1)),
arima_with_drift = ARIMA(value ~ pdq(1,1,0) + PDQ(0,1,1) + 1)
)
Regression Models
model(
tslm = TSLM(value ~ trend() + season()),
dynamic_reg = ARIMA(value ~ xreg_var)
)
Advanced Methods
model(
prophet = prophet(value),
nnetar = NNETAR(value),
tbats = TBATS(value)
)
Diagnostic Workflows
Residual Diagnostics
# Visual diagnostics
fit |>
select(model_name) |>
gg_tsresiduals()
# Ljung-Box test (should be non-significant)
augment(fit) |>
features(.innov, ljung_box, lag = 24, dof = 0)
# Residuals should be:
# 1. Uncorrelated (no patterns in ACF)
# 2. Zero mean
# 3. Constant variance
# 4. Normally distributed (for prediction intervals)
Model Comparison
# Training set accuracy
fit |> accuracy()
# Information criteria (lower is better)
fit |> glance() # AIC, AICc, BIC
# Cross-validation
ts_cv <- ts_data |>
stretch_tsibble(.init = 60, .step = 1)
cv_fit <- ts_cv |> model(arima = ARIMA(value))
cv_fc <- cv_fit |> forecast(h = 12)
cv_fc |> accuracy(ts_data)
Forecast Evaluation Metrics
- MAE: Mean Absolute Error (scale-dependent)
- RMSE: Root Mean Squared Error (penalizes large errors)
- MAPE: Mean Absolute Percentage Error (percentage)
- MASE: Mean Absolute Scaled Error (scale-independent, preferred)
# Calculate accuracy
forecast_results |>
accuracy(actual_data) |>
select(.model, MAE, RMSE, MASE) |>
arrange(MASE)
Transformations
Box-Cox Transformation
# Stabilize variance
lambda <- ts_data |>
features(value, features = guerrero) |>
pull(lambda_guerrero)
fit <- ts_data |>
model(ARIMA(box_cox(value, lambda)))
Differencing
# Remove trend (first difference)
ts_data |> mutate(diff_value = difference(value))
# Remove seasonality (seasonal difference)
ts_data |> mutate(seasonal_diff = difference(value, lag = 12))
# Determine number of differences needed
ts_data |>
features(value, unitroot_ndiffs) # Non-seasonal
ts_data |>
features(value, unitroot_nsdiffs) # Seasonal
Seasonality Handling
Detecting Seasonality
# Visual inspection
gg_season(ts_data, value)
gg_subseries(ts_data, value)
# Statistical test
ts_data |>
features(value, feat_stl) |>
select(seasonal_strength_year) # > 0.64 suggests strong seasonality
Modeling Seasonal Patterns
# Seasonal ARIMA
ARIMA(value ~ pdq() + PDQ()) # Automatic seasonal terms
# Multiple seasonality
TBATS(value) # Multiple seasonal periods
prophet(value) # Flexible seasonality
Common Patterns and Solutions
Pattern: Missing Values
# Identify gaps
scan_gaps(ts_data)
# Fill gaps with interpolation
ts_data |>
fill_gaps() |>
mutate(value = na.interp(value))
Pattern: Outliers
# Visual detection
autoplot(ts_data, value)
# Treatment options:
# 1. Remove and interpolate
# 2. Use robust methods (median-based)
# 3. Model with intervention variables
Pattern: Structural Breaks
# Split data at break point
train_data <- ts_data |> filter(Month < break_date)
test_data <- ts_data |> filter(Month >= break_date)
# Or use intervention variables in regression
Best Practices
Data Preparation
- Always convert to tsibble format first
- Check for gaps:
scan_gaps() - Visualize before modeling: time plot, seasonal plot, ACF
- Assess stationarity:
gg_tsdisplay()and unit root tests
Model Building
- Fit multiple models for comparison
- Check residual diagnostics for all candidates
- Use automatic model selection as starting point
- Refine based on domain knowledge
- Consider forecast horizon (different models excel at different horizons)
Forecasting
- Always report prediction intervals
- Use h-step ahead forecast matching business needs
- Consider computational cost for large-scale forecasting
- Re-fit models regularly as new data arrives
Evaluation
- Use time series cross-validation, not random splits
- Evaluate on multiple horizons (1-step, 3-step, 12-step)
- Use scale-independent metrics (MASE) for comparison
- Compare against simple benchmark (naive, seasonal naive)
Common Pitfalls
❌ Using non-time series methods (random split, standard regression) ✅ Use tsibble, time series cross-validation, ARIMA/ETS
❌ Ignoring residual diagnostics ✅ Always check gg_tsresiduals() and Ljung-Box test
❌ Overfitting (too many parameters) ✅ Use information criteria (AICc), cross-validation
❌ Forgetting seasonality ✅ Check gg_season() and include seasonal terms
❌ Not handling missing values ✅ Use scan_gaps() and fill_gaps()
❌ Comparing models on different data ✅ Use consistent train/test splits
Supporting Resources
Comprehensive References
- Forecasting Methods: references/forecasting-methods.md
- Simple methods, ETS, ARIMA, regression, advanced models
- Data Visualization: references/data-visualization.md
- Time plots, seasonal plots, ACF/PACF, decomposition
- Forecast Evaluation: references/forecast-evaluation.md
- Accuracy metrics, cross-validation, model selection
Workflow Templates
- Basic Forecast Workflow: templates/forecasting-workflow.md
- Step-by-step template for standard forecasting tasks
Complete Examples
- Retail Sales Forecast: examples/retail-sales-forecast.md
- End-to-end example from data to deployment
Quick Reference
Package Loading
library(fable) # Forecasting models
library(tsibble) # Time series data structures
library(feasts) # Feature extraction and statistics
library(tidyverse) # Data manipulation
Essential Functions
| Task | Function |
|---|---|
| Create tsibble | as_tsibble(index = , key = ) |
| Visualize | autoplot(), gg_season(), gg_tsdisplay() |
| Fit models | model() |
| Generate forecasts | forecast(h = ) |
| Check diagnostics | gg_tsresiduals() |
| Evaluate accuracy | accuracy() |
| Cross-validation | stretch_tsibble() |
Quick Model Comparison Template
fit <- ts_data |>
model(
naive = NAIVE(value),
snaive = SNAIVE(value),
ets = ETS(value),
arima = ARIMA(value)
)
fit |> accuracy() |> arrange(MASE)
best_model <- fit |> select(arima) # Or best performer
forecast <- best_model |> forecast(h = 12)
forecast |> autoplot(ts_data)
Integration with Other Skills
- r-datascience: Use for data preparation, EDA, visualization
- r-style-guide: Follow for R code formatting
- tdd-workflow: Use for testing forecast pipelines
- r-performance: Use for large-scale forecasting optimization
Remember: Good forecasting combines statistical rigor with domain expertise. Always validate model assumptions, use multiple models, and communicate forecast uncertainty.