Skip to content

Commit

Permalink
Rework measures definition and report
Browse files Browse the repository at this point in the history
  • Loading branch information
milanwiedemann committed Sep 25, 2024
1 parent aec0f7c commit 8b633b9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 221 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from ehrql import INTERVAL, create_measures, months, codelist_from_csv
from ehrql.tables.tpp import clinical_events, patients, practice_registrations
from ehrql.tables.tpp import clinical_events, practice_registrations

measures = create_measures()
measures.configure_dummy_data(population_size=1000)

start_date = "2023-11-01"
monthly_intervals = 8

# Dictionary of pharmacy first codes
# Create dictionary of pharmacy first codes
pharmacy_first_event_codes = {
# Community Pharmacy (CP) Blood Pressure (BP) Check Service (procedure)
"blood_pressure_service": ["1659111000000107"],
Expand All @@ -19,7 +19,7 @@
"pharmacy_first_service": ["983341000000102"],
}

# Import the codelist from CSV
# Import pharmacy first conditions codelist
pharmacy_first_conditions_codelist = codelist_from_csv(
"codelists/user-chriswood-pharmacy-first-clinical-pathway-conditions.csv",
column="code",
Expand All @@ -33,14 +33,7 @@
clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)
)

# Iterate through codelist, forming a dictionary
pharmacy_first_conditions_codes = {}
for codes, term in pharmacy_first_conditions_codelist.items():
normalised_term = term.lower().replace(" ", "_")
codes = [codes]
pharmacy_first_conditions_codes[normalised_term] = codes

# Loop through each CLINICAL SERVICE to create a measure
# Create measures for pharmacy first services
for pharmacy_first_event, codelist in pharmacy_first_event_codes.items():
condition_events = selected_events.where(
clinical_events.snomedct_code.is_in(codelist)
Expand All @@ -59,7 +52,13 @@
intervals=months(monthly_intervals).starting_on(start_date),
)

# Loop through each CLINICAL CONDITION to create a measure
# Create measures for pharmacy first conditions
pharmacy_first_conditions_codes = {}
for codes, term in pharmacy_first_conditions_codelist.items():
normalised_term = term.lower().replace(" ", "_")
codes = [codes]
pharmacy_first_conditions_codes[normalised_term] = codes

for condition_name, condition_code in pharmacy_first_conditions_codes.items():
condition_events = selected_events.where(
clinical_events.snomedct_code.is_in(condition_code)
Expand Down
6 changes: 3 additions & 3 deletions project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ expectations:
actions:
generate_pf_measures:
run: >
ehrql:v1 generate-measures analysis/report_measures.py
--output output/report/conditions_measures.csv
ehrql:v1 generate-measures analysis/measures_definition_pf_codes_conditions.py
--output output/measures/pf_codes_conditions_measures.csv
outputs:
moderately_sensitive:
measure: output/report/conditions_measures.csv
measure: output/measures/pf_codes_conditions_measures.csv
206 changes: 0 additions & 206 deletions reports/pf_report.Rmd

This file was deleted.

94 changes: 94 additions & 0 deletions reports/pharmacy_first_report.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: "Pharmacy First"
output:
html_document:
toc: true
toc_depth: 4
date: "`r format(Sys.time(), '%d %B, %Y')`"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(tidyverse)
library(here)
library(readr)
```

```{r load-data, message=FALSE, warning=FALSE}
# Load plotting function
source(here::here("lib", "functions", "function_plot_measures.R"))
# Load data
df_measures <- readr::read_csv(
here::here("output", "measures", "pf_codes_conditions_measures.csv")
)
```

```{r setup-dicts, message=FALSE, warning=FALSE}
# Define the custom labels for clinical conditions
pf_clinical_condition_dict <- c(
"count_acute_otitis_media" = "Acute Otitis Media",
"count_herpes_zoster" = "Herpes Zoster",
"count_acute_sinusitis" = "Acute Sinusitis",
"count_impetigo" = "Impetigo",
"count_infected_insect_bite" = "Infected Insect Bite",
"count_acute_pharyngitis" = "Acute Pharyngitis",
"count_uncomplicated_urinary_tract_infection" = "UTI"
)
# Define the custom labels for clinical services
pf_clinical_service_dict <- c(
"count_blood_pressure_service" = "Blood Pressure Service",
"count_contraception_service" = "Contraception Service",
"count_consultation_service" = "Consultation Service",
"count_pharmacy_first_service" = "Pharmacy First Service"
)
```

# Background

Add background here.

# Methods

This study used data from OpenSAFELY-TPP, which covers 40% of the population of England. For a description of the representativeness of this sample, please see our manuscript [here](https://wellcomeopenresearch.org/articles/7-191/v1).
Individuals were included if they were alive and registered at a TPP practice each month, across the study period.
Patients were excluded if their listed age was not between 0 and 120 years.
Counts represent patients with at least one clinical code of relevance in that month.
Patients with more than one of the same clinical code in a month were only counted once. Rates divide the count by the included study population and multiply by 1,000 to achieve a rate per 1,000 registered patients.
Counts <=7 have been redacted and all numbers rounded to the nearest 5 to avoid potential re-identification of individuals. The rates displayed were computed with these rounded counts.
Our data relies on a relevant Pharmacy First code being added to a patient's GP record.
The Pharmacy First service relies on [GP Connect - Update Record](https://digital.nhs.uk/services/gp-connect/gp-connect-in-your-organisation/gp-connect-update-record) to update a patient's GP record with consultation information from the community pharmacy.
Following the launch of the Pharmacy First service, there has been a [Gradual roll-out of GP Connect - Update Record](https://cpe.org.uk/our-news/gp-connect-update-record-rollout-and-flow-of-information/) across the approved community pharmacy IT system suppliers.

Links to the codelist for each analysis can be found beneath the relevant section.

# Results

## Clinical Services

```{r, message=FALSE, warning=FALSE}
plot_measures(df_measures,
title = "Number of consultations for each clinical service per month",
measure_names = names(pf_clinical_service_dict),
custom_labels = pf_clinical_service_dict,
y_label = "Number of codes for consultations",
)
```

## Clinical Pathways

This section focuses on the Clinical Pathways element of that Pharmacy First service.

## Clinical Condition

This section focuses on the clinical conditions within the Clinical Pathways element of that Pharmacy First service:
Here we show the number of consultations for each of the Pharmacy First Clinical Pathways Clinical Conditions.

```{r, message=FALSE, warning=FALSE}
plot_measures(df_measures,
title = "Number of consultations for each clinical condition per month",
measure_names = names(pf_clinical_condition_dict),
custom_labels = pf_clinical_condition_dict,
y_label = "Number of codes for consultations",
)
```

0 comments on commit 8b633b9

Please sign in to comment.