Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added breakdown graphs and facet function #11

Merged
merged 6 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 135 additions & 3 deletions analysis/measures_definition_pf_codes_conditions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ehrql import INTERVAL, create_measures, months, codelist_from_csv
from ehrql.tables.tpp import clinical_events, practice_registrations
from ehrql import INTERVAL, create_measures, months, codelist_from_csv, case, when
from ehrql.tables.tpp import clinical_events, practice_registrations, patients, addresses, ethnicity_from_sus

measures = create_measures()
measures.configure_dummy_data(population_size=1000)
Expand Down Expand Up @@ -28,6 +28,29 @@

registration = practice_registrations.for_patient_on(INTERVAL.end_date)

# Age bands for age breakdown
age = patients.age_on(INTERVAL.start_date)
age_band = case(
when((age >= 0) & (age < 20)).then("0-19"),
when((age >= 20) & (age < 40)).then("20-39"),
when((age >= 40) & (age < 60)).then("40-59"),
when((age >= 60) & (age < 80)).then("60-79"),
when(age >= 80).then("80+"),
when(age.is_null()).then("Missing"),
)
Comment on lines +32 to +40
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great!


# IMD groupings for IMD breakdown
imd = addresses.for_patient_on(INTERVAL.start_date).imd_rounded
max_imd = 32844
imd_quintile = case(
when((imd >=0) & (imd < int(max_imd * 1 / 5))).then("1"),
when(imd < int(max_imd * 2 / 5)).then("2"),
when(imd < int(max_imd * 3 / 5)).then("3"),
when(imd < int(max_imd * 4 / 5)).then("4"),
when(imd <= max_imd).then("5"),
otherwise="Missing"
)

# Select clinical events in interval date range
selected_events = clinical_events.where(
clinical_events.date.is_on_or_between(INTERVAL.start_date, INTERVAL.end_date)
Expand All @@ -43,7 +66,7 @@
numerator = condition_events.count_for_patient()

# Define the denominator as the number of patients registered
denominator = registration.exists_for_patient()
denominator = registration.exists_for_patient() & patients.sex.is_in(["male", "female", "intersex"])

measures.define_measure(
name=f"count_{pharmacy_first_event}",
Expand All @@ -52,6 +75,61 @@
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for age breakdown of clinical services
measures.define_measure(
name=f"count_{pharmacy_first_event}_by_age",
numerator=numerator,
denominator=denominator,
group_by={
"age_band": age_band,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for sex breakdown of clinical services
measures.define_measure(
name=f"count_{pharmacy_first_event}_by_sex",
numerator=numerator,
denominator=denominator,
group_by={
"sex": patients.sex,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for IMD breakdown of clinical services
measures.define_measure(
name=f"count_{pharmacy_first_event}_by_imd",
numerator=numerator,
denominator=denominator,
group_by={
"imd": imd_quintile,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for region breakdown of clinical services
measures.define_measure(
name=f"count_{pharmacy_first_event}_by_region",
numerator=numerator,
denominator=denominator,
group_by={
"region": registration.practice_nuts1_region_name,
},
intervals=months(monthly_intervals).starting_on(start_date),
)
Comment on lines +78 to +120
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks correct, but I think we can make this much shorter if we group by multiple features, see https://docs.opensafely.org/ehrql/explanation/measures/#grouping-by-multiple-features


# Measures for ethnicity code breakdown of clinical services
measures.define_measure(
name=f"count_{pharmacy_first_event}_by_ethnicity",
numerator=numerator,
denominator=denominator,
group_by={
"ethnicity": ethnicity_from_sus.code,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Create measures for pharmacy first conditions
pharmacy_first_conditions_codes = {}
for codes, term in pharmacy_first_conditions_codelist.items():
Expand All @@ -76,3 +154,57 @@
denominator=denominator,
intervals=months(monthly_intervals).starting_on(start_date),
)
# Measures for age breakdown of clinical conditions
measures.define_measure(
name=f"count_{condition_name}_by_age",
numerator=numerator,
denominator=denominator,
group_by={
"age_band": age_band,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for age breakdown of clinical conditions
measures.define_measure(
name=f"count_{condition_name}_by_sex",
numerator=numerator,
denominator=denominator,
group_by={
"sex": patients.sex,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for imd breakdown of clinical conditions
measures.define_measure(
name=f"count_{condition_name}_by_imd",
numerator=numerator,
denominator=denominator,
group_by={
"imd": imd_quintile,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for region breakdown of clinical conditions
measures.define_measure(
name=f"count_{condition_name}_by_region",
numerator=numerator,
denominator=denominator,
group_by={
"region": registration.practice_nuts1_region_name,
},
intervals=months(monthly_intervals).starting_on(start_date),
)

# Measures for region breakdown of clinical conditions
measures.define_measure(
name=f"count_{condition_name}_by_ethnicity",
numerator=numerator,
denominator=denominator,
group_by={
"ethnicity": ethnicity_from_sus.code,
},
intervals=months(monthly_intervals).starting_on(start_date),
)
13 changes: 13 additions & 0 deletions lib/functions/function_plot_measures.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ plot_measures <- function(
title = NULL,
x_label = NULL,
y_label = NULL,
facet_var = NULL,
color_label = NULL,
rotate_x_labels = FALSE,
axis_x_text_size = 7) {
# Check if the necessary columns exist in the data
if (date_col %in% names(data) == FALSE) {
Expand Down Expand Up @@ -99,5 +101,16 @@ plot_measures <- function(
date_labels = "%b %Y"
)

if (!is.null(facet_var)) {
facet_sym <- sym(facet_var)
plot1 <- plot1 + facet_wrap(vars(!!facet_sym), scales = "free_x")

}

# Conditionally apply x-axis label rotation if rotate_x_labels is TRUE
if (rotate_x_labels) {
plot1 <- plot1 + theme(axis.text.x = element_text(angle = 45, hjust = 1))
}

plot1
}
Loading