From 12dd6b27f0bf544159a5477c982ac0cafb65ad6f Mon Sep 17 00:00:00 2001 From: viv3ckj Date: Mon, 6 Jan 2025 15:33:42 +0000 Subject: [PATCH 1/6] Add top 5 counts to PF repo --- analysis/config.py | 6 +- ...s_definition_pf_consultation_med_counts.py | 72 +++++++++++++++++++ lib/functions/create_tables.R | 39 ++++++++++ project.yaml | 11 ++- 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 analysis/measures_definition_pf_consultation_med_counts.py diff --git a/analysis/config.py b/analysis/config.py index 0eacb9b..25ba989 100644 --- a/analysis/config.py +++ b/analysis/config.py @@ -12,4 +12,8 @@ # measures_definition_pf_medications.py start_date_measure_medications = "2023-11-01" -monthly_intervals_measure_medications = 9 \ No newline at end of file +monthly_intervals_measure_medications = 9 + +# measures_definition_pf_consultation_pf_counts.py +start_date_measure_med_counts = "2024-02-01" +monthly_intervals_measure_med_counts = 6 \ No newline at end of file diff --git a/analysis/measures_definition_pf_consultation_med_counts.py b/analysis/measures_definition_pf_consultation_med_counts.py new file mode 100644 index 0000000..5fa26b6 --- /dev/null +++ b/analysis/measures_definition_pf_consultation_med_counts.py @@ -0,0 +1,72 @@ +from ehrql import INTERVAL, create_measures, months +from ehrql.tables.tpp import ( + patients, + clinical_events, + practice_registrations, +) +from ehrql.tables.raw.tpp import medications + +from config import start_date_measure_med_counts, monthly_intervals_measure_med_counts +from codelists import ( + pharmacy_first_event_codes, + pharmacy_first_med_codes, +) +from pf_variables_library import select_events + +# Script taken from Pharmacy First Data Development (for top 10 PF meds table) + +measures = create_measures() +measures.configure_dummy_data(population_size=1000) + +start_date = start_date_measure_med_counts +monthly_intervals = monthly_intervals_measure_med_counts + +registration = practice_registrations.for_patient_on(INTERVAL.end_date) + +# Select Pharmacy First events during interval date range +pharmacy_first_events = select_events( + clinical_events, + start_date=INTERVAL.start_date, + end_date=INTERVAL.end_date).where( + clinical_events.snomedct_code.is_in( + pharmacy_first_event_codes + ) + ) + +pharmacy_first_ids = pharmacy_first_events.consultation_id +has_pharmacy_first_consultation = pharmacy_first_events.exists_for_patient() + +# Select Pharmacy First consultations during interval date range +selected_medications = select_events( + medications, + start_date=INTERVAL.start_date, end_date=INTERVAL.end_date +).where(medications.consultation_id.is_in(pharmacy_first_ids)) + +# First medication for each patient +first_selected_medication = ( + selected_medications.sort_by(selected_medications.date).first_for_patient().dmd_code +) +# Boolean variable that selected medication is part of pharmacy first med codelists +has_pharmacy_first_medication = first_selected_medication.is_in(pharmacy_first_med_codes) + +# Numerator, patients with a PF medication +# This allows me to count all (first) medications linked to a PF consultation +numerator = first_selected_medication.is_not_null() + +# Denominator, registered patients (f/m) with a PF consultation +denominator = ( + registration.exists_for_patient() + & patients.sex.is_in(["male", "female"]) + & has_pharmacy_first_consultation +) + +measures.define_measure( + name="pf_medication_count", + numerator = first_selected_medication.is_not_null(), + denominator=denominator, + group_by={ + "dmd_code": first_selected_medication, + "pharmacy_first_med": has_pharmacy_first_medication, + }, + intervals=months(monthly_intervals).starting_on(start_date), +) diff --git a/lib/functions/create_tables.R b/lib/functions/create_tables.R index 910fbb0..575c457 100644 --- a/lib/functions/create_tables.R +++ b/lib/functions/create_tables.R @@ -129,3 +129,42 @@ create_clinical_conditions_codes_table <- function(title) { heading.subtitle.font.size = "small" ) } + +# Create top 5 table grouped by pharmacy_first_med status +# Data needs to have the following columns: +# pharmacy_first_med +# term +# count +# ratio_by_group +gt_top_meds <- function(data) { + data |> + gt( + groupname_col = "pharmacy_first_med", + rowname_col = "term" + ) %>% + tab_header( + title = "Top 5 medications linked to Pharmacy First consultations", + subtitle = "Timeframe: 1st Feb 2024 to 31st July 2024" + ) %>% + cols_label( + term = md("**Medication**"), + count = md("**Count**"), + ratio_by_group = md("**%**") + ) %>% + fmt_number( + columns = count, + decimals = 0 + ) %>% + fmt_percent( + columns = ratio_by_group, + decimals = 1 + ) %>% + tab_style( + style = cell_text(weight = "bold"), + locations = cells_row_groups(groups = everything()) + ) %>% + tab_stub_indent( + rows = everything(), + indent = 3 + ) +} \ No newline at end of file diff --git a/project.yaml b/project.yaml index 913b03b..e02eb17 100644 --- a/project.yaml +++ b/project.yaml @@ -47,4 +47,13 @@ actions: --output output/population/pf_population.csv.gz outputs: highly_sensitive: - cohort: output/population/pf_population.csv.gz \ No newline at end of file + cohort: output/population/pf_population.csv.gz + + generate_pf_med_counts_measures: + run: > + ehrql:v1 generate-measures analysis/measures_definition_pf_consultation_med_counts.py + --dummy-tables dummy_tables + --output output/measures/consultation_med_counts_measures.csv + outputs: + moderately_sensitive: + measure: output/measures/consultation_med_counts_measures.csv \ No newline at end of file From 306004c3250a846cdc528348e7cde953838b7801 Mon Sep 17 00:00:00 2001 From: viv3ckj Date: Mon, 6 Jan 2025 15:34:01 +0000 Subject: [PATCH 2/6] Add xlsx from url function --- lib/functions/eps_erd_prescribing_data.r | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 lib/functions/eps_erd_prescribing_data.r diff --git a/lib/functions/eps_erd_prescribing_data.r b/lib/functions/eps_erd_prescribing_data.r new file mode 100644 index 0000000..ff510b7 --- /dev/null +++ b/lib/functions/eps_erd_prescribing_data.r @@ -0,0 +1,36 @@ +library(tidyverse) +library(janitor) +library(here) +library(httr) + +# Function to download and read the xlsx files +read_xlsx_from_url <- function(url_list, sheet = NULL, skip = NULL, ...) { + temp_file <- tempfile(fileext = ".xlsx") + GET( + url_list, + write_disk(temp_file, overwrite = TRUE) + ) + readxl::read_xlsx( + temp_file, + col_names = TRUE, + .name_repair = janitor::make_clean_names, + sheet = sheet, + skip = skip, + ... + ) +} + +df <- read_xlsx_from_url( + "https://github.com/user-attachments/files/17774058/EPS.and.eRD.Prescribing.Dashboard.July.2024.xlsx", + skip = 2, + sheet = "Historical Data" +) + +df_filtered <- df %>% + select(month, region_code, practice_code, eps_items, erd_items) %>% + filter(month %in% c(202402, 202403, 202404, 202405, 202406, 202407)) %>% + mutate(month = ym(month)) + +df_filtered |> write_csv( + here("lib", "validation", "data", "eps_erd_prescribing_2024-02-01_to_2024-07-01.csv") +) From 600e53a5261bd57347b5fba396f76fd65443a4b3 Mon Sep 17 00:00:00 2001 From: viv3ckj Date: Mon, 6 Jan 2025 16:09:12 +0000 Subject: [PATCH 3/6] Add same day measures (meds and condition) to descriptive stats --- ...easures_definition_pf_descriptive_stats.py | 60 ++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/analysis/measures_definition_pf_descriptive_stats.py b/analysis/measures_definition_pf_descriptive_stats.py index 61db72a..3839a3a 100644 --- a/analysis/measures_definition_pf_descriptive_stats.py +++ b/analysis/measures_definition_pf_descriptive_stats.py @@ -2,7 +2,7 @@ from ehrql.tables.raw.tpp import medications from ehrql.tables.tpp import practice_registrations, patients, clinical_events -from pf_variables_library import select_events_from_codelist, select_events_by_consultation_id +from pf_variables_library import select_events from codelists import ( pharmacy_first_med_codelist, pharmacy_first_consultation_codelist, @@ -20,24 +20,38 @@ registration = practice_registrations.for_patient_on(INTERVAL.end_date) # Function to retrieve consultation ids from clinical events that are PF consultations -pharmacy_first_ids = select_events_from_codelist( - clinical_events, pharmacy_first_consultation_codelist +pharmacy_first_ids = select_events( + clinical_events, codelist=pharmacy_first_consultation_codelist ).consultation_id # Function to retrieve selected events using pharmacy first ids -selected_clinical_events = select_events_by_consultation_id( - clinical_events, pharmacy_first_ids +selected_clinical_events = select_events( + clinical_events, consultation_ids=pharmacy_first_ids ).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) -selected_med_events = select_events_by_consultation_id(medications, pharmacy_first_ids).where( +selected_med_events = select_events( + medications, consultation_ids=pharmacy_first_ids).where( medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) ) # Create variable which contains boolean values of whether pharmacy first event exists for patient -has_pf_consultation = select_events_from_codelist(selected_clinical_events, pharmacy_first_consultation_codelist).exists_for_patient() +has_pf_consultation = select_events( + selected_clinical_events, codelist=pharmacy_first_consultation_codelist).exists_for_patient() # PF consultations with PF clinical condition -has_pf_condition = select_events_from_codelist(selected_clinical_events, pharmacy_first_conditions_codelist).exists_for_patient() +has_pf_condition = select_events( + selected_clinical_events, codelist=pharmacy_first_conditions_codelist).exists_for_patient() + +# Dates of pharmacy first consultations +pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_ids).date + +# Specify whether a patient has been prescribed a PF medication on the same day as a PF consultation code +has_pfmed_on_pfdate = selected_med_events.where(medications.date.is_in(pharmacy_first_dates)) + +# Specify whether a patient has a PF condition +has_pfpathway_on_pfdate = has_pf_condition.where( + has_pf_condition.date.is_in(pharmacy_first_dates) +) # PF consultations with prescribed PF medication has_pf_medication = selected_med_events.where( @@ -52,6 +66,12 @@ ) measures.define_defaults(denominator=denominator) +# Denominator without the pf_consultation constraint +study_population = ( + registration.exists_for_patient() + & patients.sex.is_in(["male", "female"]) +) + # Measures for PF consultations with PF medication measures.define_measure( name="pf_with_pfmed", @@ -71,3 +91,27 @@ numerator=has_pf_condition & has_pf_medication, intervals=months(monthly_intervals).starting_on(start_date), ) + +# Measures for PF medications prescribed on the same day as PF consultation +measures.define_measure( + name="pfmed_on_pfdate", + numerator=has_pfmed_on_pfdate, + denominator=study_population, + intervals=months(monthly_intervals).starting_on(start_date), +) + +# Measures for PF conditions diagnosed on the same day as PF consultation +measures.define_measure( + name="pfpathway_on_pfdate", + numerator=has_pfpathway_on_pfdate, + denominator=study_population, + intervals=months(monthly_intervals).starting_on(start_date), +) + +# Measures for PF conditions diagnosed and PF med prescribed on the same day as PF consultation +measures.define_measure( + name="pfmed_and_pfpathway_on_pfdate", + numerator=has_pfmed_on_pfdate & has_pfpathway_on_pfdate, + denominator=study_population, + intervals=months(monthly_intervals).starting_on(start_date), +) From 6ca389fd5718f1c08a7ddf3179464a1a3ed59202 Mon Sep 17 00:00:00 2001 From: viv3ckj Date: Tue, 7 Jan 2025 12:25:47 +0000 Subject: [PATCH 4/6] Address run errors --- ...asures_definition_pf_consultation_med_counts.py | 8 ++++---- .../measures_definition_pf_descriptive_stats.py | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/analysis/measures_definition_pf_consultation_med_counts.py b/analysis/measures_definition_pf_consultation_med_counts.py index 5fa26b6..5069806 100644 --- a/analysis/measures_definition_pf_consultation_med_counts.py +++ b/analysis/measures_definition_pf_consultation_med_counts.py @@ -8,8 +8,8 @@ from config import start_date_measure_med_counts, monthly_intervals_measure_med_counts from codelists import ( - pharmacy_first_event_codes, - pharmacy_first_med_codes, + pharmacy_first_consultation_codelist, + pharmacy_first_med_codelist, ) from pf_variables_library import select_events @@ -29,7 +29,7 @@ start_date=INTERVAL.start_date, end_date=INTERVAL.end_date).where( clinical_events.snomedct_code.is_in( - pharmacy_first_event_codes + pharmacy_first_consultation_codelist ) ) @@ -47,7 +47,7 @@ selected_medications.sort_by(selected_medications.date).first_for_patient().dmd_code ) # Boolean variable that selected medication is part of pharmacy first med codelists -has_pharmacy_first_medication = first_selected_medication.is_in(pharmacy_first_med_codes) +has_pharmacy_first_medication = first_selected_medication.is_in(pharmacy_first_med_codelist) # Numerator, patients with a PF medication # This allows me to count all (first) medications linked to a PF consultation diff --git a/analysis/measures_definition_pf_descriptive_stats.py b/analysis/measures_definition_pf_descriptive_stats.py index 3839a3a..310bfa6 100644 --- a/analysis/measures_definition_pf_descriptive_stats.py +++ b/analysis/measures_definition_pf_descriptive_stats.py @@ -34,6 +34,10 @@ medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) ) +selected_clinical_pathways = select_events( + clinical_events, codelist=pharmacy_first_conditions_codelist +).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) + # Create variable which contains boolean values of whether pharmacy first event exists for patient has_pf_consultation = select_events( selected_clinical_events, codelist=pharmacy_first_consultation_codelist).exists_for_patient() @@ -43,15 +47,15 @@ selected_clinical_events, codelist=pharmacy_first_conditions_codelist).exists_for_patient() # Dates of pharmacy first consultations -pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_ids).date +pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_consultation_codelist).date # Specify whether a patient has been prescribed a PF medication on the same day as a PF consultation code -has_pfmed_on_pfdate = selected_med_events.where(medications.date.is_in(pharmacy_first_dates)) +has_pfmed_on_pfdate = selected_med_events.where(medications.date.is_in(pharmacy_first_dates)).exists_for_patient() # Specify whether a patient has a PF condition -has_pfpathway_on_pfdate = has_pf_condition.where( - has_pf_condition.date.is_in(pharmacy_first_dates) -) +has_pfpathway_on_pfdate = selected_clinical_pathways.where( + selected_clinical_pathways.date.is_in(pharmacy_first_dates) +).exists_for_patient() # PF consultations with prescribed PF medication has_pf_medication = selected_med_events.where( From 77db975975f0c16c9031c51ff5bf818c42d714bc Mon Sep 17 00:00:00 2001 From: viv3ckj Date: Tue, 7 Jan 2025 17:10:52 +0000 Subject: [PATCH 5/6] Modify selected_med_events to link to med_codelist and not pf_id --- ...easures_definition_pf_descriptive_stats.py | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/analysis/measures_definition_pf_descriptive_stats.py b/analysis/measures_definition_pf_descriptive_stats.py index 310bfa6..54bef4e 100644 --- a/analysis/measures_definition_pf_descriptive_stats.py +++ b/analysis/measures_definition_pf_descriptive_stats.py @@ -24,16 +24,26 @@ clinical_events, codelist=pharmacy_first_consultation_codelist ).consultation_id +# Dates of pharmacy first consultations +pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_consultation_codelist).date + # Function to retrieve selected events using pharmacy first ids selected_clinical_events = select_events( clinical_events, consultation_ids=pharmacy_first_ids ).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) -selected_med_events = select_events( +# Med events linked to pharmacy first consultation IDs +selected_pfid_med_events = select_events( medications, consultation_ids=pharmacy_first_ids).where( medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) ) +# Med events that are not linked by ID but are linked to PF Med codelist +selected_med_events = medications.where(medications.dmd_code.is_in(pharmacy_first_med_codelist) + ).where(medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) +) + +# Events linked to a PF clinical pathway, and not by PF ID selected_clinical_pathways = select_events( clinical_events, codelist=pharmacy_first_conditions_codelist ).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) @@ -46,9 +56,6 @@ has_pf_condition = select_events( selected_clinical_events, codelist=pharmacy_first_conditions_codelist).exists_for_patient() -# Dates of pharmacy first consultations -pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_consultation_codelist).date - # Specify whether a patient has been prescribed a PF medication on the same day as a PF consultation code has_pfmed_on_pfdate = selected_med_events.where(medications.date.is_in(pharmacy_first_dates)).exists_for_patient() @@ -58,8 +65,8 @@ ).exists_for_patient() # PF consultations with prescribed PF medication -has_pf_medication = selected_med_events.where( - selected_med_events.dmd_code.is_in(pharmacy_first_med_codelist) +has_pf_medication = selected_pfid_med_events.where( + selected_pfid_med_events.dmd_code.is_in(pharmacy_first_med_codelist) ).exists_for_patient() # Define the denominator as the number of patients registered @@ -70,12 +77,6 @@ ) measures.define_defaults(denominator=denominator) -# Denominator without the pf_consultation constraint -study_population = ( - registration.exists_for_patient() - & patients.sex.is_in(["male", "female"]) -) - # Measures for PF consultations with PF medication measures.define_measure( name="pf_with_pfmed", @@ -100,7 +101,6 @@ measures.define_measure( name="pfmed_on_pfdate", numerator=has_pfmed_on_pfdate, - denominator=study_population, intervals=months(monthly_intervals).starting_on(start_date), ) @@ -108,7 +108,6 @@ measures.define_measure( name="pfpathway_on_pfdate", numerator=has_pfpathway_on_pfdate, - denominator=study_population, intervals=months(monthly_intervals).starting_on(start_date), ) @@ -116,6 +115,5 @@ measures.define_measure( name="pfmed_and_pfpathway_on_pfdate", numerator=has_pfmed_on_pfdate & has_pfpathway_on_pfdate, - denominator=study_population, intervals=months(monthly_intervals).starting_on(start_date), ) From b1c9000f22e142abb28fe83ba7bb01f5bdbbec75 Mon Sep 17 00:00:00 2001 From: Milan Wiedemann Date: Wed, 8 Jan 2025 12:47:24 +0000 Subject: [PATCH 6/6] Rework measure counting linked PF conditions and meds --- ...easures_definition_pf_descriptive_stats.py | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/analysis/measures_definition_pf_descriptive_stats.py b/analysis/measures_definition_pf_descriptive_stats.py index 54bef4e..92a766d 100644 --- a/analysis/measures_definition_pf_descriptive_stats.py +++ b/analysis/measures_definition_pf_descriptive_stats.py @@ -8,10 +8,13 @@ pharmacy_first_consultation_codelist, pharmacy_first_conditions_codelist, ) -from config import start_date_measure_descriptive_stats, monthly_intervals_measure_descriptive_stats +from config import ( + start_date_measure_descriptive_stats, + monthly_intervals_measure_descriptive_stats, +) measures = create_measures() -measures.configure_dummy_data(population_size=1000) +measures.configure_dummy_data(population_size=100) measures.configure_disclosure_control(enabled=True) start_date = start_date_measure_descriptive_stats @@ -19,101 +22,98 @@ registration = practice_registrations.for_patient_on(INTERVAL.end_date) -# Function to retrieve consultation ids from clinical events that are PF consultations -pharmacy_first_ids = select_events( - clinical_events, codelist=pharmacy_first_consultation_codelist -).consultation_id +# Select clinical events and medications for measures INTERVAL +selected_events = clinical_events.where( + clinical_events.date.is_on_or_between( + INTERVAL.start_date, + INTERVAL.end_date, + ) +) +selected_medications = medications.where( + medications.date.is_on_or_between( + INTERVAL.start_date, + INTERVAL.end_date, + ) +) + +# Select all Pharmacy First consultation events +pf_consultation_events = select_events( + selected_events, + codelist=pharmacy_first_consultation_codelist, +) -# Dates of pharmacy first consultations -pharmacy_first_dates = select_events(clinical_events, codelist=pharmacy_first_consultation_codelist).date +# Extract Pharmacy First consultation IDs and dates +pf_ids = pf_consultation_events.consultation_id +pf_dates = pf_consultation_events.date -# Function to retrieve selected events using pharmacy first ids -selected_clinical_events = select_events( - clinical_events, consultation_ids=pharmacy_first_ids -).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) +has_pf_consultation = pf_consultation_events.exists_for_patient() -# Med events linked to pharmacy first consultation IDs -selected_pfid_med_events = select_events( - medications, consultation_ids=pharmacy_first_ids).where( - medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) +# Select Pharmacy First conditions by ID and date +selected_pf_id_conditions = selected_events.where( + selected_events.consultation_id.is_in(pf_ids) +).where(selected_events.snomedct_code.is_in(pharmacy_first_conditions_codelist)) + +selected_pf_date_conditions = ( + selected_events.where(selected_events.consultation_id.is_not_in(pf_ids)) + .where(selected_events.date.is_in(pf_dates)) + .where(selected_events.snomedct_code.is_in(pharmacy_first_conditions_codelist)) ) -# Med events that are not linked by ID but are linked to PF Med codelist -selected_med_events = medications.where(medications.dmd_code.is_in(pharmacy_first_med_codelist) - ).where(medications.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date) +has_pf_id_condition = selected_pf_id_conditions.exists_for_patient() +has_pf_date_condition = selected_pf_date_conditions.exists_for_patient() + +# Select Pharmacy First Medications by ID and date +selected_pf_id_medications = selected_medications.where( + selected_medications.consultation_id.is_in(pf_ids) +).where(selected_medications.dmd_code.is_in(pharmacy_first_med_codelist)) + +selected_pf_date_medications = ( + selected_medications.where(selected_medications.consultation_id.is_not_in(pf_ids)) + .where(selected_medications.date.is_in(pf_dates)) + .where(selected_medications.dmd_code.is_in(pharmacy_first_med_codelist)) ) -# Events linked to a PF clinical pathway, and not by PF ID -selected_clinical_pathways = select_events( - clinical_events, codelist=pharmacy_first_conditions_codelist -).where(clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)) - -# Create variable which contains boolean values of whether pharmacy first event exists for patient -has_pf_consultation = select_events( - selected_clinical_events, codelist=pharmacy_first_consultation_codelist).exists_for_patient() - -# PF consultations with PF clinical condition -has_pf_condition = select_events( - selected_clinical_events, codelist=pharmacy_first_conditions_codelist).exists_for_patient() - -# Specify whether a patient has been prescribed a PF medication on the same day as a PF consultation code -has_pfmed_on_pfdate = selected_med_events.where(medications.date.is_in(pharmacy_first_dates)).exists_for_patient() - -# Specify whether a patient has a PF condition -has_pfpathway_on_pfdate = selected_clinical_pathways.where( - selected_clinical_pathways.date.is_in(pharmacy_first_dates) -).exists_for_patient() - -# PF consultations with prescribed PF medication -has_pf_medication = selected_pfid_med_events.where( - selected_pfid_med_events.dmd_code.is_in(pharmacy_first_med_codelist) -).exists_for_patient() - -# Define the denominator as the number of patients registered -denominator = ( - registration.exists_for_patient() - & patients.sex.is_in(["male", "female"]) - & has_pf_consultation +has_pf_id_medication = selected_pf_id_medications.exists_for_patient() +has_pf_date_medication = selected_pf_date_medications.exists_for_patient() + +# Define measures +measures.define_defaults( + denominator=( + registration.exists_for_patient() + & patients.sex.is_in(["male", "female"]) + & has_pf_consultation + ), + intervals=months(monthly_intervals).starting_on(start_date), ) -measures.define_defaults(denominator=denominator) -# Measures for PF consultations with PF medication +# Measures linked by Pharmacy First consultation ID measures.define_measure( - name="pf_with_pfmed", - numerator=has_pf_medication, - intervals=months(monthly_intervals).starting_on(start_date), + name="pfmed_with_pfid", + numerator=has_pf_id_medication, ) -# Measures for PF consultations with PF condition + measures.define_measure( - name="pf_with_pfcondition", - numerator=has_pf_condition, - intervals=months(monthly_intervals).starting_on(start_date), + name="pfcondition_with_pfid", + numerator=has_pf_id_condition, ) -# Measures for PF consultations with both PF medication and condition measures.define_measure( - name="pf_with_pfmed_and_pfcondition", - numerator=has_pf_condition & has_pf_medication, - intervals=months(monthly_intervals).starting_on(start_date), + name="pfmed_and_pfcondition_with_pfid", + numerator=has_pf_id_medication & has_pf_id_condition, ) -# Measures for PF medications prescribed on the same day as PF consultation +# Measures linked by Pharmacy First consultation date measures.define_measure( name="pfmed_on_pfdate", - numerator=has_pfmed_on_pfdate, - intervals=months(monthly_intervals).starting_on(start_date), + numerator=has_pf_date_medication, ) -# Measures for PF conditions diagnosed on the same day as PF consultation measures.define_measure( - name="pfpathway_on_pfdate", - numerator=has_pfpathway_on_pfdate, - intervals=months(monthly_intervals).starting_on(start_date), + name="pfcondition_on_pfdate", + numerator=has_pf_date_condition, ) -# Measures for PF conditions diagnosed and PF med prescribed on the same day as PF consultation measures.define_measure( - name="pfmed_and_pfpathway_on_pfdate", - numerator=has_pfmed_on_pfdate & has_pfpathway_on_pfdate, - intervals=months(monthly_intervals).starting_on(start_date), + name="pfmed_and_pfcondition_on_pfdate", + numerator=has_pf_date_medication & has_pf_date_condition, )