Tracking fiscal policy measures since 1970
Source:vignettes/policy-measures.Rmd
policy-measures.RmdThe OBR’s Policy Measures Database (PMD) lists every individual tax measure scored at a UK fiscal event since 1970, and every spending measure since 2010, with the Exchequer effect in GBP million for each year of the forecast horizon. It is the dataset behind virtually every “Chancellor’s Budget worth GBP X” headline in the financial press.
The OBR distributes the PMD as a single Excel workbook with a
non-trivial layout. obr is the only programmatic wrapper
for it that exists.
The chunks below that download data are shown as code only; for a quick offline preview, run any chunk in an R session with internet access.
Pulling the database
library(obr)
pmd <- get_policy_measures() # tax + spending, all years
obr_provenance(pmd)$vintage # which PMD vintage was downloadedReturned columns are type, event,
measure, head, fiscal_year,
value_mn. Positive values are revenue-raising for tax
measures and spending-increasing for spending measures.
Filtering by fiscal event
type, search, and since filter
at the source so you don’t have to subset a 100k-row data frame
manually.
# Every tax measure scored at the October 2024 Budget,
# ordered by 2025-26 effect
oct24 <- get_policy_measures(type = "tax", since = "2025-26")
oct24 <- oct24[grepl("October 2024", oct24$event) &
oct24$fiscal_year == "2025-26", ]
oct24 <- oct24[order(-oct24$value_mn), ]
head(oct24[, c("measure", "head", "value_mn")])Searching by theme
search is a regular expression (case-insensitive)
applied to both the measure description and the Treasury head.
# Every alcohol-duty measure since 2010
alc <- get_policy_measures(type = "tax", search = "alcohol", since = "2010-11")
unique(alc$event)This lets you build thematic time series for empirical work: e.g. cumulative tax raised from energy measures over a Parliament, or the share of personal-tax revenue from threshold freezes.
Aggregating to the Budget scorecard
policy_measures_summary() collapses the long format to
net Exchequer effect by event and fiscal year. This is what fits in an
IFS Green Budget chart.
pm <- get_policy_measures(type = "tax", since = "2024-25")
agg <- policy_measures_summary(pm)
agg[agg$event == "Budget October 2024", ]Provenance is preserved through aggregation: the returned
obr_tbl still records which PMD vintage produced the
numbers.
obr_provenance(agg)$vintageWorked example: contribution of each fiscal event
For attribution work (“which Budget did most of the lifting?”), aggregate by event for a fixed target year.
pm <- get_policy_measures(type = "tax")
parl <- pm[pm$fiscal_year == "2027-28" &
grepl("(October 2024|2025|2026)", pm$event), ]
agg <- policy_measures_summary(parl)
agg[order(agg$event), c("event", "value_mn")]The pattern - filter once, summarise once - mirrors how analysts read the OBR’s own scorecard tables in the EFO.
Cross-vintage comparison
Because each PMD release re-prints the full history with any
reclassifications, you can compare measure-level numbers across PMD
vintages by downloading two and joining on event +
measure. (At the time of writing, the OBR re-uses the
march-2025 slug across vintages for the PMD; the package’s
URL resolver finds whichever file is currently live and records its MD5
fingerprint, so cross-vintage comparison is hash-verifiable.)