A seeded, reproducible synthetic dataset for Fake NHS Trust, a fictional
large acute trust with two hospitals, covering 1 April 2023 to 31 March 2026. It is built
to look like the extracts an analyst actually receives: a patient administration system
with ADT events, an emergency department tracking board, outpatient appointments and
referral-to-treatment pathways, CT, MRI and ultrasound in a radiology system, and an
endoscopy vendor export. The data is deliberately messy, every imperfection is catalogued
and recorded in an answers table, and a derived layer rebuilds spells, episodes and
national-return aggregates from the raw events so the difference between
event data and aggregated data can be explored directly.
No row describes a real person; every NHS number carries the fake_ prefix.
An index of every table with row counts, sizes and download links, and the first 100 rows of each from the sample.
One diagram per layer, generated from the data: every link is inferred from column names and then measured, so clean keys and messy cross-system identifiers are drawn differently with their match rates.
About 40,000 patients with all of their rows in every table, so joins hold. Parquet, with a CSV zip for tools that cannot read Parquet.
https://thomuk.github.io/synthetic-hospital-data/data/v2/sample/
· browse the tablesEvery row, one Parquet asset per file. Asset names are the paths under full/ with / replaced by __.
DuckDB reads the Parquet straight from the URL.
import duckdb
base = "https://thomuk.github.io/synthetic-hospital-data/data/v2/sample/"
duckdb.sql(f"""
SELECT tretspef_first, count(*) AS spells, median(speldur) AS median_los
FROM read_parquet('{base}derived/spells.parquet')
WHERE emergency GROUP BY 1 ORDER BY 2 DESC
""").show()
library(duckdb); con <- dbConnect(duckdb())
base <- "https://thomuk.github.io/synthetic-hospital-data/data/v2/sample/"
dbGetQuery(con, sprintf("SELECT count(*) FROM read_parquet('%sderived/spells.parquet')", base))
A DuckDB-WASM console pre-loaded with the sample, a schema browser, and an explainer walking from an ADT event to a spell to a midnight census with runnable queries.