--- title: "Tracking fiscal policy measures since 1970" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Tracking fiscal policy measures since 1970} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` The 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 ```{r, eval = FALSE} library(obr) pmd <- get_policy_measures() # tax + spending, all years obr_provenance(pmd)$vintage # which PMD vintage was downloaded ``` Returned 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. ```{r, eval = FALSE} # 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. ```{r, eval = FALSE} # 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. ```{r, eval = FALSE} 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. ```{r, eval = FALSE} obr_provenance(agg)$vintage ``` ## Worked example: contribution of each fiscal event For attribution work ("which Budget did most of the lifting?"), aggregate by event for a fixed target year. ```{r, eval = FALSE} 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.)