Understanding fable: Managing Time Series Forecasting in R Programming
Second in a series on time series featuring ggtime and other time series packages.
Understanding fable: Managing Time Series Forecasting in R Programming
Second in a series on time series featuring ggtime and other time series packages.

In a separate post I showed how the ggtime series helps analysts spot seasonal spikes, lag relationships, and trend shifts in a tsibble. That post is the first of a series on time series forcasting using ggtime (though the package is not the only one you can iuse for forecasting).
I mentioned fable briefly in that post. The explanation in that post assumed you already knew what fable was doing in the syntax and gave an elementary explanation of its role in the program.
If you didn’t understand it, it’s okay. This piece, the second in the series, fills that familiarity gap.
The fable package is part of the tidyverse family, the same package ecosystem that gives you tsibble and feasts. It was built to replace the older forecast package, which worked with base ts objects instead of tidy data. fable fits models the same way dplyr summarizes data, through a consistent, pipeable syntax that scales from one series to hundreds.
How fable fits into Data Analysis
Forecasting in R used to mean juggling separate objects and functions for each model type, with little consistency between them. The fable package changes that by treating every model the same way: as a row in a table. You specify what to fit, fable fits it, and the result sits in a structure you can filter, compare, and plot using the same dplyr verbs you already use for everything else.
This matters for a lean analytics team. You don’t need a separate script for every model type. One pipeline handles exponential smoothing, ARIMA, and simpler baseline models together. Adding a new model later means adding one line, not rewriting the workflow.
A Mabel from a Model: Understanding fable’s Core Object
Every fable workflow starts with model() , and it returns an object that serves as a variation of a datatable. The** **model() function fits one or more model specifications against a tsibble and stores the results in a “mable,” short for model table.
So in the code example below, the flights in the nycflights23 package dataset is being filtered into hourly data. they are then placed into a tsibble data object

Each row of a mable represents a series, and each model column holds a fitted model object for that series. A mable prints like a regular tibble, but the cells contain full model fits rather than plain values. This arrangement lets you carry multiple models through the same pipeline without juggling separate variables for each one.

Model Syntax Basics
Fable models accept two levels of control through the ETS() function. The parameters let you select the function to choose automatically, or to specify the trend structure yourself.

The ETS() function with no formula lets the function search across trend and seasonal component combinations and pick the best fit based on information criteria. So in this example, the search is being done on the flight_count data.
The syntax ETS(flight_count ~ trend(“A”) + season(“M”)) locks in an additive trend and multiplicative season instead on the flight_count data. This arrangement is useful once you understand a series well enough to know its seasonal swings scale with the level of the data rather than staying constant.
The period = 7 syntax tells the model how many time steps make up one full seasonal cycle. In this example, the daily_flights objects is indexed by day. So a period of 7 means the program will "look for a pattern that repeats every 7 days." Specifying a period removes that guesswork and tells fable directly how to treat a season — in this instance every 7 observations is one seasonal round trip. The seven-day call is exactly the weekly rhythm that will be visible in the plot.
Auto-selection is the right default for a first pass. Explicit specification earns its place once you’ve looked at the seasonal pattern closely, ideally through a ggtime plot, and have a reason to constrain the model.
From Model to Forecast
The next step after crafting a fitted mable is the forecast. The forecast() function is the step that turns a fitted model into future values.

The forecast() function returns a distribution object for each future period, not a single number. That distribution is what generates the shaded prediction intervals you see in the plot, giving you a sense of forecast uncertainty instead of a false sense of precision.
The autoplot() takes that forecast object along with the historical tsibble and draws both together, so the transition from observed data to projected data is visible in one chart rather than split across two. Here is the output from out example.

The dense, spiky oscillation running through 2023 is the weekly rhythm that the whole “why daily instead of monthly” argument was built around.
The visual shows that the flight counts climb on weekdays and drop on weekends, over and over, all year. That sharp single-day dip near the end of 2023 stands out from the rest of the pattern and likely reflects a holiday period with a lighter flight schedule. In practice the outlier is probably worth a quick check against the raw data if you want to confirm the exact date.
The blue fan starting at the edge of the historical data is the three-month forecast, with the darker band showing the 80% prediction interval and the lighter band the 95% interval. Notice how quickly that fan widens. Daily data carries more noise than monthly data, so the model’s uncertainty grows fast as it projects further from the last observed point, which is a fair trade for the weekly-pattern accuracy we gained by dropping down to daily granularity in the first place.
Where fable Fits in the Pipeline
The ggtime packageshows you the pattern in a series. fable takes that same tsibble and turns the pattern into a forecast, using the identical data structure, so nothing needs to be reshaped in between. Once you’re comfortable with the basics here, the natural next step is comparing multiple models formally, which is exactly what the ggtime-to-fable piece in this series walks through with accuracy() and a training and test split.
What This Means for Your Work
With fable, you’re not decoding new syntax and new forecasting concepts in the same paragraph. It is a foundation beneficial for a consultancy producing recurring client reports. The bend result is faster onboarding. Anyone on the team can look at a mable and know what it represents, without needing a walkthrough every time.
As I has mentioned in the beginning this post is the second of a series of post on times series forecasting: There’s another forecasting post listed below, covering caretForecast, as well as the first post in the series, ggtime. Learning fable’s core objects first, the mable, the formula syntax, and the forecast distribution- will make every later piece in the series easier to follow.
메타데이터
- post_id
- 4b2c7a6c8fe1
- slug
- understanding-fable-managing-time-series-forecasting-in-r-programming-4b2c7a6c8fe1
- url
- https://medium.com/codex/understanding-fable-managing-time-series-forecasting-in-r-programming-4b2c7a6c8fe1
- canonical_url
- https://medium.com/codex/understanding-fable-managing-time-series-forecasting-in-r-programming-4b2c7a6c8fe1
- author_url
- https://medium.com/@zimanaanalytics
- status
- ok
- fetched_at
- 2026-07-10 11:40:45