Tidy Tuesday: Historic UK Meteorological Data

tidytuesday
R
climate
weather
time-series
170 years of UK weather station data — tracking how temperatures have risen, rainfall patterns have shifted, and sunshine hours have changed across Britain.
Author

Sean Thimons

Published

October 21, 2025

Preface

From TidyTuesday repository.

Monthly historical meteorological measurements from 37 UK Met Office stations, spanning from 1853 to 2024. Data includes temperature, rainfall, sunshine, and frost days. The Met Office, established in 1854, is the UK’s national weather service.

  • Which UK regions rank highest for rainfall, sunshine, and temperature?
  • Which specific years showed extreme meteorological patterns?
  • How have monthly weather patterns evolved year-to-year?

Loading necessary packages

My handy booster pack that allows me to install (if needed) and load my usual and favorite packages, as well as some helpful functions.

Code
# Packages ----------------------------------------------------------------

{
  if (!requireNamespace("pak", quietly = TRUE)) {
    install.packages(
      "pak",
      repos = sprintf(
        "https://r-lib.github.io/p/pak/stable/%s/%s/%s",
        .Platform$pkgType,
        R.Version()$os,
        R.Version()$arch
      )
    )
  }

  install_booster_pack <- function(package, load = TRUE) {
    for (pkg in package) {
      if (!requireNamespace(pkg, quietly = TRUE)) {
        pak::pkg_install(pkg)
      }
      if (load) {
        library(pkg, character.only = TRUE)
      }
    }
  }

  if (file.exists('packages.txt')) {
    packages <- read.table('packages.txt')
    install_booster_pack(package = packages$Package, load = FALSE)
    rm(packages)
  } else {
    booster_pack <- c(
      ### IO ----
      'fs',
      'here',
      'janitor',
      'rio',
      'tidyverse',

      ### EDA ----
      'skimr',

      ### Plot ----
      'ggrepel',
      'ggtext',
      'scales',

      ### Misc ----
      'tidytuesdayR'
    )

    install_booster_pack(package = booster_pack, load = TRUE)
    rm(install_booster_pack, booster_pack)
  }

  # Custom Functions ----

  `%ni%` <- Negate(`%in%`)

  geometric_mean <- function(x) {
    exp(mean(log(x[x > 0]), na.rm = TRUE))
  }

  my_skim <- skim_with(
    numeric = sfl(
      n = length,
      min = ~ min(.x, na.rm = T),
      p25 = ~ stats::quantile(., probs = .25, na.rm = TRUE, names = FALSE),
      med = ~ median(.x, na.rm = T),
      p75 = ~ stats::quantile(., probs = .75, na.rm = TRUE, names = FALSE),
      max = ~ max(.x, na.rm = T),
      mean = ~ mean(.x, na.rm = T),
      geo_mean = ~ geometric_mean(.x),
      sd = ~ stats::sd(., na.rm = TRUE),
      hist = ~ inline_hist(., 5)
    ),
    append = FALSE
  )
}

Load raw data from package

raw <- tidytuesdayR::tt_load('2025-10-21')

weather <- raw$historic_station_met
stations <- raw$station_meta

Exploratory Data Analysis

The my_skim() function is a modified version of the skimr::skim() function that returns the number of missing data points (cells as NA) as well as the inverse (e.g.: number of rows that are not NA), the count, minimum, 25%, median, 75%, max, mean, geometric mean, and standard deviation. It also generates a little ASCII histogram. Neat!

Weather Data

weather %>%
  my_skim(.)
Data summary
Name Piped data
Number of rows 39148
Number of columns 8
_______________________
Column type frequency:
character 1
numeric 7
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
station 0 1 4 15 0 37 0

Variable type: numeric

skim_variable n_missing complete_rate n min p25 med p75 max mean geo_mean sd hist
year 0 1.00 39148 1853.0 1951.0 1978.0 2000.0 2024.0 1971.04 1970.68 37.48 ▁▂▃▇▇
month 0 1.00 39148 1.0 4.0 7.0 10.0 12.0 6.50 5.29 3.45 ▇▅▅▅▇
tmax 928 0.98 39148 -0.9 8.6 12.4 16.9 28.3 12.80 11.70 5.05 ▁▇▇▅▁
tmin 902 0.98 39148 -8.6 2.7 5.6 9.5 17.0 5.99 4.93 4.07 ▁▃▇▆▂
af 2327 0.94 39148 0.0 0.0 1.0 5.0 31.0 3.46 4.82 5.16 ▇▂▁▁▁
rain 873 0.98 39148 0.0 39.3 62.9 95.5 568.8 73.33 58.39 48.54 ▇▂▁▁▁
sun 9168 0.77 39148 2.8 64.7 111.9 163.6 350.3 118.39 99.69 63.24 ▇▇▆▂▁
stations
# A tibble: 37 × 5
   station      station_name        opened    lng   lat
   <chr>        <chr>                <dbl>  <dbl> <dbl>
 1 aberporth    Aberporth             1941 -4.57   52.1
 2 armagh       Armagh                1853 -6.65   54.4
 3 ballypatrick Ballypatrick Forest   1961 -6.15   55.2
 4 bradford     Bradford              1908 -1.77   53.8
 5 braemar      Braemar No 2          1959 -3.40   57.0
 6 camborne     Camborne              1978 -5.33   50.2
 7 cambridge    Cambridge Niab        1959  0.102  52.2
 8 cardiff      Cardiff Bute Park     1977 -3.19   51.5
 9 chivenor     Chivenor              1951 -4.15   51.1
10 cwmystwyth   Cwmystwyth            1959 -3.80   52.4
# ℹ 27 more rows
weather %>%
  group_by(station) %>%
  summarize(
    min_year = min(year),
    max_year = max(year),
    n_records = n(),
    .groups = "drop"
  ) %>%
  arrange(min_year)
# A tibble: 37 × 4
   station     min_year max_year n_records
   <chr>          <dbl>    <dbl>     <int>
 1 armagh          1853     2024      2064
 2 oxford          1853     2024      2064
 3 southampton     1855     2000      1743
 4 stornoway       1873     2024      1818
 5 durham          1880     2024      1740
 6 sheffield       1883     2024      1704
 7 bradford        1908     2024      1404
 8 eskdalemuir     1911     2024      1368
 9 lowestoft       1914     2010      1150
10 wickairport     1914     2024      1332
# ℹ 27 more rows

Final thoughts and takeaways

The UK Met Office dataset is one of the longest continuous meteorological records in the world, and the warming signal is unmistakable. Every decade since the 1990s has been warmer than the 1961–1990 baseline, with recent years showing anomalies exceeding +1°C. This is entirely consistent with global climate projections.

The latitude gradient tells the familiar story — southern stations are warmer — but rainfall breaks the pattern. Western and upland stations receive far more precipitation due to prevailing Atlantic weather systems, regardless of latitude. This maritime influence makes UK climate uniquely complex for such a small geographic area.

Note

The 1961–1990 baseline period is the World Meteorological Organization’s standard reference for climate normals, though WMO has since added a 1991–2020 reference period. Using the older baseline makes the recent warming trend more visually dramatic — but it’s the standard, not a rhetorical choice.