ons

Lifecycle: stable License: MIT

An R package for downloading data from the Office for National Statistics.

What is the ONS?

The Office for National Statistics is the UK’s national statistical authority. It produces the headline economic data that drives policy and markets — GDP, inflation, unemployment, wages, trade, house prices, retail sales, and population estimates. Its releases move sterling, set the agenda for the Bank of England’s Monetary Policy Committee, and underpin economic research across the UK.

The ONS publishes thousands of time series through its website, each identified by a four-character CDID code. The data is freely available, but using it programmatically requires knowing these codes, constructing download URLs with topic paths and dataset identifiers, parsing CSV files with metadata headers, and handling mixed-frequency data where annual, quarterly, and monthly observations appear in a single file.

This package replaces all of that with named functions that return clean data frames.

How is this different from existing packages?

The onsr package on CRAN wraps the ONS Beta API — but that API does not host most headline economic time series. GDP, CPI, unemployment, wages, and trade data are not available through it. onsr is useful for Census data and regional breakdowns, but cannot access the series most people actually want. It was last actively developed in 2021.

This package takes a different approach. It fetches data directly from the ONS website’s CSV time series endpoint, which covers every published CDID. You get named functions — ons_gdp(), ons_cpi(), ons_unemployment() — that handle series codes, URL construction, frequency filtering, and caching internally.

Why does this package exist?

The data is freely available, but using it programmatically requires knowing obscure CDID codes (GDP growth is IHYQ, the CPI annual rate is D7G7), constructing URLs with topic paths and dataset identifiers, parsing CSV files that mix metadata headers with data rows, and filtering out duplicate observations where annual, quarterly, and monthly data appear in the same file. Every analyst who works with ONS data writes the same boilerplate.

# Without this package
url <- paste0(
  "https://www.ons.gov.uk/generator?format=csv",
  "&uri=/economy/grossdomesticproductgdp/timeseries/ihyq/pn2"
)
raw <- readLines(url)
# ... skip metadata rows, parse periods, filter frequency, handle errors ...

# With this package
library(ons)
ons_gdp(from = "2020-01-01")

Installation

Install the development version from GitHub:

# install.packages("remotes")
remotes::install_github("charlescoverdale/ons")

Functions

Function Description From
ons_gdp() Quarterly GDP (growth, YoY, level, nominal) 1948
ons_monthly_gdp() Monthly GDP index 1997
ons_cpi() Consumer price inflation (CPI, CPIH, RPI; rate or index) 1987
ons_unemployment() Unemployment rate (16+, seasonally adjusted) 1971
ons_employment() Employment rate (total, male, female) 1971
ons_inactivity() Economic inactivity (thousands) 1971
ons_wages() Average weekly earnings (level, growth, real) 2000
ons_trade() Trade balance, exports, imports (GBP millions) 1948
ons_retail_sales() Retail sales index (volume or value) 1988
ons_house_prices() UK average house price (GBP) 1968
ons_productivity() Output per hour or per worker (index) 1971
ons_population() Mid-year population estimates 1971
ons_public_finances() Public sector net borrowing (GBP millions) 1993
ons_get() Fetch any series by CDID code Any
ons_search() Search the ONS catalogue by keyword
clear_cache() Delete locally cached data files

Examples

How fast is the UK economy growing?

library(ons)

# Quarterly GDP growth
gdp <- ons_gdp(from = "2000-01-01")
tail(gdp, 6)
#>         date value
#>   2024-07-01   0.2
#>   2024-10-01   0.3
#>   2025-01-01   0.7
#>   2025-04-01   0.2
#>   2025-07-01   0.1
#>   2025-10-01   0.1

How has inflation changed over time?

# CPI annual rate
cpi <- ons_cpi(from = "2024-01-01")
tail(cpi, 6)
#>         date value
#>   2025-08-01   3.8
#>   2025-09-01   3.8
#>   2025-10-01   3.6
#>   2025-11-01   3.2
#>   2025-12-01   3.4
#>   2026-01-01   3.0

# CPIH or RPI
ons_cpi(measure = "cpih", from = "2024-01-01")
ons_cpi(measure = "rpi", type = "index", from = "2024-01-01")

What is the UK unemployment rate?

# Unemployment rate (16+, SA)
unemp <- ons_unemployment(from = "2020-01-01")
tail(unemp, 6)
#>         date value
#>   2025-06-01   4.7
#>   2025-07-01   4.8
#>   2025-08-01   5.0
#>   2025-09-01   5.1
#>   2025-10-01   5.1
#>   2025-11-01   5.2

How have wages changed over time?

# Average weekly earnings (GBP)
wages <- ons_wages(from = "2024-01-01")
tail(wages, 6)
#>         date value
#>   2025-07-01   728
#>   2025-08-01   733
#>   2025-09-01   734
#>   2025-10-01   740
#>   2025-11-01   740
#>   2025-12-01   735

# Year-on-year growth or real terms
ons_wages(measure = "growth", from = "2024-01-01")
ons_wages(measure = "real", from = "2024-01-01")

What is the average UK house price?

# UK average house price
hp <- ons_house_prices(from = "2024-01-01")
tail(hp, 6)
#>         date average_price_gbp annual_change_pct
#>   2025-07-01            270432               3.0
#>   2025-08-01            271808               2.5
#>   2025-09-01            270827               2.3
#>   2025-10-01            270548               2.0
#>   2025-11-01            272043               2.8
#>   2025-12-01            270259               2.4

What is the UK’s trade balance?

# Trade balance (GBP millions, negative = deficit)
trade <- ons_trade(from = "2024-01-01")
tail(trade, 6)
#>         date value
#>   2025-07-01 -2152
#>   2025-08-01 -2151
#>   2025-09-01 -4530
#>   2025-10-01 -5790
#>   2025-11-01 -5564
#>   2025-12-01 -4340

# Exports or imports separately
ons_trade(measure = "exports", from = "2024-01-01")

How much is the UK government borrowing?

# Public sector net borrowing (GBP millions)
pf <- ons_public_finances(from = "2024-01-01")
tail(pf, 6)
#>         date  value
#>   2025-08-01  15239
#>   2025-09-01  22471
#>   2025-10-01  16183
#>   2025-11-01  10380
#>   2025-12-01  13355
#>   2026-01-01 -30366

Fetching any series by CDID code

# If you know the ONS CDID code, use ons_get() directly
# Find codes at https://www.ons.gov.uk/timeseriestool

# GDP growth vs CPI inflation
ons_get(c("IHYQ", "D7G7"), from = "2024-01-01", to = "2024-06-30")
#>         date cdid value
#>   2024-01-01 IHYQ   0.8
#>   2024-04-01 IHYQ   0.6
#>   2024-01-01 D7G7   4.0
#>   2024-02-01 D7G7   3.4
#>   2024-03-01 D7G7   3.2
#>   2024-04-01 D7G7   2.3
#>   2024-05-01 D7G7   2.0
#>   2024-06-01 D7G7   2.0

# Search for series by keyword
ons_search("GDP growth")

Caching

All downloads are cached locally in your user cache directory. Subsequent calls return the cached copy instantly — no network request is made.

# Force a fresh download
ons_gdp(from = "2020-01-01", cache = FALSE)

# Remove files older than 7 days
clear_cache(max_age_days = 7)

# Remove all cached files
clear_cache()

This package is part of a family of R packages for UK economic and fiscal data. They share a consistent interface — named functions, tidy data frames, local caching — and are designed to work together. All outputs join cleanly on date columns.

Package What it covers
boe Bank of England data (Bank Rate, SONIA, gilt yields, exchange rates, mortgage rates)
hmrc HMRC tax receipts, corporation tax, stamp duty, R&D credits, and tax gap data
obr OBR fiscal forecasts and the Public Finances Databank
inflateR Adjust values for inflation using CPI or GDP deflator data

Issues

Please report bugs or requests at https://github.com/charlescoverdale/ons/issues.