Fitting a trend line with TSLM

Today let's understand how to fit a straight trend line through a time series, using TSLM(), and read exactly what the line's own numbers mean.

Northwind is a small SaaS company that tracks its monthly active users, MAU for short. Here are 48 months of it, January 2022 through December 2025. MAU climbs from 1,225 users to a high of 5,290, but it is not a straight climb, it wobbles up and down along the way.

Look at that shape for a second. It rises overall, but every few months it dips before climbing again. Draw one straight line through that wobble, and Northwind's growth reduces to two numbers: a starting point and a monthly rate.

What TSLM() fits, and what trend() means as a predictor

TSLM() stands for time series linear model. It fits the same ordinary linear regression you would get from lm(), except it is built to work on a tsibble, the tidyverse's structure for a table indexed by time, and it understands a few special time-aware predictors that lm() does not.

trend() is one of those predictors. It is nothing more than the row number of the series: 1 for the first month, 2 for the second, all the way up to 48 for Northwind's last month, December 2025.

Build Northwind's 48 months as a tsibble, then fit TSLM(mau ~ trend()), which reads as "explain mau using trend() as the only predictor."

RInteractive R
# Build Northwind's 48 months of MAU as a tsibble, then fit TSLM(mau ~ trend()) library(tsibble) library(fable) library(fabletools) library(dplyr) set.seed(45) trend_vals <- seq(1200, 5000, length.out = 48) e <- numeric(48) e[1] <- rnorm(1, 0, 0.06 * trend_vals[1]) for (i in 2:48) { e[i] <- 0.7 * e[i - 1] + rnorm(1, 0, 0.045 * trend_vals[i]) } mau <- round(trend_vals + e) nw <- tsibble(month = yearmonth("2022 Jan") + 0:47, mau = mau, index = month) print(nw, n = 5) #> # A tsibble: 48 x 2 [1M] #> month mau #> <mth> <dbl> #> 1 2022 Jan 1225 #> 2 2022 Feb 1257 #> 3 2022 Mar 1322 #> 4 2022 Apr 1366 #> 5 2022 May 1409 #> # ℹ 43 more rows fit <- nw |> model(TSLM(mau ~ trend())) print(fit) #> # A mable: 1 x 1 #> `TSLM(mau ~ trend())` #> <model> #> 1 <TSLM>

  

model() is fabletools' function for fitting any time series model onto a tsibble. It hands back a mable, short for model table, one row holding the whole fitted TSLM object inside a single cell. The print above just confirms which model that cell holds; the next step pulls the real numbers back out of it.