Repository for building example Sankey diagrams for bed reconfiguration.
The repository contains two related workflows:
2 State: compare one snapshot state against another3 State: compare previous, current, and proposed states
.
|-- data/
| |-- ward_snapshots_current_proposed.xlsx
| |-- moves_current_proposed.xlsx
| |-- ward_snapshots_3_state.xlsx
| |-- moves_3_state.xlsx
| `-- processed/
| |-- snapshot_summary.csv
| |-- moves_summary.csv
| `-- 3_state/
| |-- snapshot_summary.csv
| `-- moves_summary.csv
|-- outputs/
|-- R/
| |-- 2 State/
| | |-- 01_process_beds.R
| | |-- 02_sankey.R
| | `-- 03_export_selfcontained.R
| `-- 3 State/
| |-- 01_process_beds.R
| |-- 02_sankey.R
| `-- 03_export_selfcontained.R
|-- lancs_ward_sankey_example.Rproj
`-- README.md
Each state option follows the same three-step pattern:
01_process_beds.RReads Excel input files fromdata/, standardises columns, and writes processed summaries todata/processed/.02_sankey.RReads the processed CSV files, applies filters and status settings, and writes the Sankey HTML output tooutputs/.03_export_selfcontained.RRe-runs the Sankey build and writes a self-contained HTML file for easier sharing.
Open the project in RStudio, or set the working directory to the project root before sourcing scripts.
source(here::here("R", "2 State", "01_process_beds.R"))
source(here::here("R", "2 State", "02_sankey.R"))
source(here::here("R", "2 State", "03_export_selfcontained.R"))Outputs:
outputs/sankey_diagram_bed_movements_2_state.htmloutputs/sankey_diagram_bed_movements_2_state_selfcontained.html
source(here::here("R", "3 State", "01_process_beds.R"))
source(here::here("R", "3 State", "02_sankey.R"))
source(here::here("R", "3 State", "03_export_selfcontained.R"))Outputs:
outputs/sankey_diagram_bed_movements_3_state.htmloutputs/sankey_diagram_bed_movements_3_state_selfcontained.html
These are defined near the top of
R/2 State/01_process_beds.R:
snapshot_path <- here::here("data", "ward_snapshots_current_proposed.xlsx")
moves_path <- here::here("data", "moves_current_proposed.xlsx")To use a different dataset, change those file names to the workbook you want to process.
These are defined near the top of
R/3 State/01_process_beds.R:
snapshot_path <- here::here("data", "ward_snapshots_3_state.xlsx")
moves_path <- here::here("data", "moves_3_state.xlsx")To switch to a different 3-state dataset, update these paths and rerun
01_process_beds.R.
The processing scripts write standardised CSV files that are then used by the Sankey scripts.
output_dir <- here::here("data", "processed")This creates:
data/processed/snapshot_summary.csvdata/processed/moves_summary.csv
output_dir <- here::here("data", "processed", "3_state")This creates:
data/processed/3_state/snapshot_summary.csvdata/processed/3_state/moves_summary.csv
If you change the raw input files, rerun the relevant 01_process_beds.R
script before rerunning the Sankey export.
The main parameters to edit are at the bottom of each 02_sankey.R script.
For 2-state, edit:
left_status <- "Current - January 2026"
right_status <- "Proposed"For 3-state, edit:
previous_status <- "Previous - April 2025"
current_status <- "Current - January 2026"
proposed_status <- "Proposed"These values must match the Status values in the snapshot input files.
For 2-state, edit these variables in R/2 State/02_sankey.R:
start_hospitals <- c("RPH")
end_hospitals <- c("RPH")Use NULL to remove the filter:
start_hospitals <- NULL
end_hospitals <- NULLFor 3-state, edit:
previous_hospitals <- c("RPH")
current_hospitals <- c("RPH")
proposed_hospitals <- c("RPH")You can also use different hospitals for each state if required.
For 2-state:
start_divisions <- c("MED")
end_divisions <- c("MED")For 3-state:
previous_divisions <- c("MED")
current_divisions <- c("MED")
proposed_divisions <- c("MED")Set these back to NULL to include all divisions.
If you want the Sankey script to read from a different processed location,
change the paths near the top of each 02_sankey.R.
Example from 2-state:
snapshot_path <- here::here("data", "processed", "snapshot_summary.csv")
moves_path <- here::here("data", "processed", "moves_summary.csv")Example from 3-state:
snapshot_path <- here::here(
"data",
"processed",
"3_state",
"snapshot_summary.csv"
)
moves_path <- here::here(
"data",
"processed",
"3_state",
"moves_summary.csv"
)In normal use, these do not need to change unless you want to maintain multiple processed datasets side by side.
The export names are set at the bottom of each 02_sankey.R file and in each
03_export_selfcontained.R file.
Current outputs are:
sankey_diagram_bed_movements_2_state.htmlsankey_diagram_bed_movements_2_state_selfcontained.htmlsankey_diagram_bed_movements_3_state.htmlsankey_diagram_bed_movements_3_state_selfcontained.html
The processing scripts expect the snapshot workbooks to include columns such as:
DivisionHospitalWardSpecialty / SBUBed TypeBedsStatus
The moves workbooks are expected to include origin and destination fields,
including hospital, division, ward, specialty, bed type, and Beds.
For the 3-state moves file, a stage field is also expected and is mapped to
move_stage.
- Update the relevant
*_hospitalsvariables in02_sankey.R. - Leave all division filters as
NULLunless you also want a division cut. - Rerun
02_sankey.Rand, if needed,03_export_selfcontained.R.
- Update
snapshot_pathandmoves_pathin the relevant01_process_beds.R. - Run
01_process_beds.R. - Check that the status values in the new data match the status names used in
02_sankey.R. - Run
02_sankey.R.
- Leave hospital filters as
NULL. - Set the division vectors in
02_sankey.R. - Rerun the Sankey script.
- The repository does not currently include a
renv.lockfile. 03_export_selfcontained.Rrequires Pandoc. The script checks common installation paths and usesRSTUDIO_PANDOCif available.- The Sankey scripts stop with an error if a chosen status does not exist in the processed snapshot data.
This repository has been created and developed by: