R β NHS Quickstart
π§ͺ Statistics Β· Epidemiology Β· Shiny dashboards Β· SQL Server
Why R in the NHS
R has a deep statistics ecosystem (survival, time series, epidemiology) and first-class reporting (R Markdown/Quarto) with Shiny for interactive apps. The NHS-R community provides patterns, training, and reusable code.
Great for: Clinician-Researchers Β· BI Analysts (stats/QA) Β· Data Scientists.
βοΈ 10-minute installβ
- Windows (R + RStudio)
- macOS / Linux
- Install R (4.3+) from CRAN and RStudio Desktop.
- Open RStudio β Console:
install.packages(c("tidyverse","DBI","odbc","shiny","ggplot2","janitor","readxl"))
For SQL Server access, install Microsoft ODBC Driver 18 for SQL Server on Windows.
- Install R (4.3+) via your package manager and RStudio.
- In R:
install.packages(c("tidyverse","DBI","odbc","shiny","ggplot2","janitor","readxl"))
For SQL Server access, install the ODBC Driver 18 for SQL Server for your OS.
π βHello NHSβ analysisβ
Create a new R script hello_nhs.R:
hello_nhs.R
library(tidyverse)
df <- tibble::tibble(
date = as.Date("2025-01-01") + 0:4,
attendances = c(120, 135, 128, 142, 131)
)
cat("Admissions summary\n")
print(summary(df$attendances))
ggplot(df, aes(date, attendances)) +
geom_line() +
geom_point() +
labs(title = "Daily Attendances", x = "Date", y = "Count")
Run in RStudio (Ctrl/Cmd+Enter) β a plot window appears.
π Query SQL Server (DBI + odbc)β
Store connection settings in .Renviron (project root or home):
.Renviron
SQLSERVER_SERVER=YOURSERVER
SQLSERVER_DATABASE=NHS_Analytics
Then in R:
query_sqlserver.R
library(DBI)
library(odbc)
library(dplyr)
con <- dbConnect(odbc::odbc(),
Driver = "ODBC Driver 18 for SQL Server",
Server = Sys.getenv("SQLSERVER_SERVER"),
Database = Sys.getenv("SQLSERVER_DATABASE"),
Trusted_Connection = "Yes",
Encrypt = "Yes",
TrustServerCertificate = "Yes" # set per Trust policy
)
df <- dbGetQuery(con, "
SELECT TOP (100)
practice_id,
total_appointments,
attendance_rate
FROM dbo.vw_PracticeKPI
ORDER BY total_appointments DESC
")
print(head(df))
dbDisconnect(con)
π Minimal Shiny dashboard (15 min)β
Create app.R:
app.R
library(shiny)
library(dplyr)
library(ggplot2)
df <- tibble::tibble(
practice_id = rep(c("A","B","C"), each = 3),
month = rep(c("2025-05","2025-06","2025-07"), times = 3),
appointments = c(120,135,128, 100,110,115, 95,102,108)
)
ui <- fluidPage(
tags$h2("NHS KPI (Demo)"),
selectInput("m", "Month", choices = unique(df$month)),
plotOutput("chart")
)
server <- function(input, output, session){
output$chart <- renderPlot({
d <- filter(df, month == input$m)
ggplot(d, aes(practice_id, appointments)) +
geom_col(fill = "#005EB8") +
labs(title = paste("Appointments by Practice β", input$m),
x = "Practice", y = "Appointments")
})
}
shinyApp(ui, server)
Run:
shiny::runApp()
π§° NHS-ready packagesβ
| Package | Use case |
|---|---|
tidyverse | data wrangling (dplyr/tidyr/readr) |
ggplot2 | charts and statistical graphics |
DBI + odbc | connect to SQL Server |
janitor | clean names, quick QA checks |
shiny | interactive dashboards for clinicians |
rmarkdown / quarto | reproducible reports |
arrow | fast Parquet/Feather IO |
π§± Reproducible reports (R Markdown / Quarto)β
Create report.Rmd:
---
title: "Weekly KPI"
output: html_document
---
```{r}
library(tidyverse)
df <- tibble::tibble(
month = c("2025-05","2025-06","2025-07"),
appointments = c(355, 380, 351)
)
knitr::kable(df)
```
```{r, fig.height=3}
library(ggplot2)
ggplot(df, aes(month, appointments, group=1)) +
geom_line() + geom_point() +
labs(title="Monthly Appointments")
```
Render with Knit in RStudio.
π IG & safety checklistβ
- Use synthetic/de-identified data in examples.
- Keep secrets out of code; prefer .Renviron locally and a secret store in prod.
- Avoid free-text PHI in logs/plots; aggregate and apply suppression rules.
- Document dataset sources, owners, and refresh cadence in the repo README.
- For Shiny in production, put behind SSO (Entra ID/NHS Login) and add usage logging.
π Measuring impactβ
- Velocity: time from data pull β plot/report.
- Reliability: refresh success rate for scheduled scripts/apps.
- Quality: peer review via PRs; validation checks.
- Adoption: weekly active users for Shiny; report opens.
π See alsoβ
Whatβs next?
Youβve completed the Learn β R stage. Keep momentum: