The R ecosystem knows a ridiculous number of time series classes. So, I decided to create a new universal standard that finally covers everyone’s use case…
tsbox, just realeased on CRAN, provides a set of tools that are agnostic towards existing time series classes. It is built around a set of converters, which convert time series stored as ts, xts, data.frame, data.table, tibble, zoo, tsibble or timeSeries to each other.
To install the stable version from CRAN:
To get an idea how easy it is to switch from one class to another, consider this:
library(tsbox) x.ts <- ts_c(mdeaths, fdeaths) x.xts <- ts_xts(x.ts) x.df <- ts_df(x.xts) x.tbl <- ts_tbl(x.df) x.dt <- ts_tbl(x.tbl) x.zoo <- ts_zoo(x.dt) x.tsibble <- ts_tsibble(x.zoo) x.timeSeries <- ts_timeSeries(x.tsibble)
We jump form good old
ts objects to
xts, store our time series in various
data frames and convert them to some highly specialized time series formats.
tsbox is class-agnostic
Because these converters work nicely, we can use them to make functions class-agnostic. If a class-agnostic function works for one class, it works for all:
ts_scale(x.ts) ts_scale(x.xts) ts_scale(x.df) ts_scale(x.dt) ts_scale(x.tbl)
ts_scale normalizes one or multiple series, by subtracting the mean and
dividing by the standard deviation. It works like a ‘generic’ function: You can
apply it on any time series object, and it will return an object of the same
class as its input.
So, whether we want to smooth, scale, differentiate, chain-link, forecast, regularize, or seasonally adjust a series, we can use the same commands to whatever time series at hand. tsbox offers a comprehensive toolkit for the basics of time series manipulation. Here are some additional operations:
ts_pc(x.ts) # percentage change rates ts_forecast(x.xts) # forecast, by exponential smoothing ts_seas(x.df) # seasonal adjustment, by X-13 ts_frequency(x.dt, "year") # convert to annual frequency ts_span(x.tbl, "-1 year") # limit time span to final year
tsbox is frequency-agnostic
There are many more. Because they all start with
ts_, you can use
auto-complete to see what’s around. Most conveniently, there is a time series
plot function that works for all classes and frequencies:
ts_plot( `Airline Passengers` = AirPassengers, `Lynx trappings` = ts_df(lynx), `Deaths from Lung Diseases` = ts_xts(fdeaths), title = "Airlines, trappings, and deaths", subtitle = "Monthly passengers, annual trappings, monthly deaths" )
There is also a version that uses ggplot2 and has the same syntax.
Time series in data frames
You may have wondered why we treated data frames as a time series class. The spread of dplyr and data.table has given data frames a boost and made them one of the most popular data structures in R. So, storing time series in a data frame is an obvious consequence. And even if you don’t intend to keep time series in data frames, this is still the format in which you import and export your data. tsbox makes it easy to switch from data frames to time series and back.
Make existing functions class-agnostic
tsbox includes tools to
make existing functions class-agnostic. To do so, the
ts_ function can be used
to wrap any function that works with time series. For a function that works on
"ts" objects, this is as simple as that:
ts_rowsums <- ts_(rowSums) ts_rowsums(ts_c(mdeaths, fdeaths))
ts_ returns a function, which can be used with or without a name.
In case you are wondering, tsbox uses data.table as a backend and makes use of its incredibly efficient reshaping facilities, its joins, and rolling joins. And thanks to anytime, tsbox will be able to recognize almost any date format without manual intervention.
So, if you’ve been struggling with R’s time series class, we hope that you found this blog helpful.
More postsEFS vs. NFS for RStudio on Kubernetes (AWS): Configuration and considerations
Patrick SchratzAccessing Google's API via OAuth2
Patrick Schratzseasonal 1.9: Accessing composite output
Christoph SaxGoogle Season of Docs with R: useR! Information Board
Ben UbahRunning old versions of TeXlive with tinytex
Kirill Müllertsbox 0.3.1: extended functionality
Christoph SaxCelebrating one-year anniversary as RStudio Full Service Certified Partner
Cosima Meyer, Patrick SchratzDeprecating a pkgdown site served via GitHub Pages
Patrick Schratz, Kirill Müllergfortran support for R on macOS
Patrick SchratzSeasonal Adjustment of Multiple Series
Christoph SaxDynamic build matrix in GitHub Actions
Kirill MüllerSetting up a load-balanced Jitsi Meet instance
Patrick SchratzDevOps Expert (f/m/d, 60-100%)
cynkra teamMaintaining multiple identities with Git
Kirill MüllerRelational data models in R
Angel D'az, Kirill Müllertempdisagg: converting quarterly time series to daily
Christoph Saxtsbox 0.2: supporting additional time series classes
Christoph SaxDevOps System Engineer (40-60%)
cynkra teamIntroducing dm: easy juggling of tables and relations
Balthasar Sagertsbox 0.1: class-agnostic time series
Christoph SaxTime series of the world, unite!
Christoph SaxDone “Establishing DBI”!?