Skip to content

Commit

Permalink
Graphs for events and conditions added
Browse files Browse the repository at this point in the history
  • Loading branch information
viv3ckj committed Aug 23, 2024
1 parent 2824469 commit 7a80e1f
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 71 deletions.
57 changes: 36 additions & 21 deletions analysis/report_measures.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@
# Pharmacy First service (qualifier value)
"pharmacy_first_service": ["983341000000102"],
}
# The following codes come from codelists/user-chriswood-pharmacy-first-clinical-pathway-conditions.csv file.
# Currently written as a hardcoded dictionary to allow for easy for looping (ln66-83), but will be imported from codelist csv in future commits.
# Pharmacy First seven clinical conditions codelist
pharmacy_first_conditions_codes = {
# Community Pharmacy (CP) Blood Pressure (BP) Check Service (procedure)
"acute_otitis_media": ["3110003"],
# Community Pharmacy (CP) Contraception Service (procedure)
"herpes_zoster": ["4740000"],
# Community Pharmacist (CP) Consultation Service for minor illness (procedure)
"acute_sinusitis": ["15805002"],
# Pharmacy First service (qualifier value)
"impetigo": ["48277006"],
# Community Pharmacy (CP) Contraception Service (procedure)
"infected_insect_bite": ["262550002"],
# Community Pharmacist (CP) Consultation Service for minor illness (procedure)
"acute_pharyngitis": ["363746003"],
# Pharmacy First service (qualifier value)
"uncomplicated_urinary_tract_infection": ["1090711000000102"],
}

registration = practice_registrations.for_patient_on(INTERVAL.end_date)

Expand All @@ -24,7 +43,7 @@
)

# Loop through each condition to create a measure
for condition_name, codelist in pharmacy_first_event_codes.items():
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 @@ -36,33 +55,29 @@
# Define the denominator as the number of patients registered
denominator = registration.exists_for_patient()

# Define the measure
measures.define_measure(
name=f"count_{condition_name}",
name=f"count_{pharmacy_first_event}",
numerator=numerator,
denominator=denominator,
intervals=months(8).starting_on("2023-11-01")
)

# # Count pharmacy first codes
# pharmacy_first_code_counts = {}
# Loop through each CLINICAL condition to create a measure
for condition_name, condition_code in pharmacy_first_conditions_codes.items():
condition_events = selected_events.where(
clinical_events.snomedct_code.is_in(condition_code)
)

# for code_desc, code in pharmacy_first_event_codes.items():
# count_codes_query = selected_events.where(
# selected_events.snomedct_code.is_in(code)
# ).count_for_patient()
# pharmacy_first_code_counts[f"count_{code_desc}"] = count_codes_query
# Define the numerator as the count of events for the condition
numerator = condition_events.count_for_patient()


# for measures_name, code_counts in pharmacy_first_code_counts.items():
# measures.define_measure(
# name=measures_name,
# numerator=code_counts,
# group_by={
# "practice_region": registration.practice_nuts1_region_name
# },
# denominator=patients.exists_for_patient(),
# intervals=intervals,
# )
# Define the denominator as the number of patients registered
denominator = registration.exists_for_patient()


measures.define_measure(
name=f"count_{condition_name}",
numerator=numerator,
denominator=denominator,
intervals=months(8).starting_on("2023-11-01")
)
43 changes: 31 additions & 12 deletions analysis/reports/pf_report.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pre[class] {
</style>



```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
Expand All @@ -34,13 +33,13 @@ library(readr)
```
$~$
<br>

## Background <a name="background"></a>

Add background here.

$~$
<br>

## Methods <a name="methods"></a>

Expand All @@ -58,8 +57,7 @@ Links to the codelist for each analysis can be found beneath the relevant sectio

This report contains the following sections:



* [Clinical Services](#services)
* [Clinical Pathways](#pathways)
* [Clinical condition](#condition)
* [Days of the week](#dotw)
Expand All @@ -82,9 +80,11 @@ This report contains the following sections:
* [Age](#contra_age)
* [Region](#contra_region)

$~$
<br>

## Clinical services
## Clinical Services <a name="services"></a>

<br>

```{r, message=FALSE, warning=FALSE}
# Load plotting function
Expand All @@ -94,12 +94,15 @@ df_measures <- readr::read_csv(
here::here("output", "report", "conditions_measures.csv")
)
plot1_conditions <- plot_measures(df_measures,
plot_services <- plot_measures(df_measures,
title = "Number of consultations for each clinical service per month",
x_label = "Month",
y_label = "Number of Consultations",
color_label = "Clinical Service")
print(plot1_conditions)
measure_names = c("count_blood_pressure_service",
"count_contraception_service",
"count_consultation_service",
"count_pharmacy_first_service"),
y_label = "Number of codes for consultations",
)
print(plot_services)
```

## Clinical Pathways <a name="pathways"></a>
Expand All @@ -116,6 +119,22 @@ Here we show the number of consultations for each of the Pharmacy First Clinical

> LINE CHART WITH COUNT OF EACH CLINICAL CONDITION
```{r, message=FALSE, warning=FALSE}
plot_conditions <- plot_measures(df_measures,
title = "Number of consultations for each clinical condition per month",
measure_names = c("count_acute_otitis_media",
"count_herpes_zoster",
"count_acute_sinusitis",
"count_impetigo",
"count_infected_insect_bite",
"count_acute_pharyngitis",
"count_uncomplicated_urinary_tract_infection"),
y_label = "Number of codes for consultations",
)
print(plot_conditions)
```

### Counts by day of the week <a name="dotw"></a>
Here we show the number of consultations for the Pharmacy First Clinical Pathways by day of the week the consultation was conducted. (Mainly of interest to show what happens at weekends etc e.g. when GP practices are closed).

Expand Down
3 changes: 2 additions & 1 deletion analysis/reports/pf_report.html

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion codelists/codelists.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"files": {}
"files": {
"user-chriswood-pharmacy-first-clinical-pathway-conditions.csv": {
"id": "user/chriswood/pharmacy-first-clinical-pathway-conditions/7ec97762",
"url": "https://www.opencodelists.org/codelist/user/chriswood/pharmacy-first-clinical-pathway-conditions/7ec97762/",
"downloaded_at": "2024-08-22 12:53:00.167017Z",
"sha": "bed7f74add5c2d2ac6f7120d89f5ba94e57a28cb"
}
}
}
1 change: 1 addition & 0 deletions codelists/codelists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
user/chriswood/pharmacy-first-clinical-pathway-conditions/7ec97762
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
code,term
1090711000000102,Uncomplicated urinary tract infection
15805002,Acute sinusitis
262550002,Infected insect bite
3110003,Acute otitis media
363746003,Acute pharyngitis
4740000,Herpes zoster
48277006,Impetigo
65 changes: 52 additions & 13 deletions lib/functions/function_plot_measures.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#' Creates a line plot of measures over time, with customisable labels and colours.
#'
#' @param data A dataframe containing the data to plot.
#' @param measure_names Strings specifiying the names of measure columns to be plotted.
#' @param title A string specifying the title of the plot. Default is NULL.
#' @param x_label A string specifying the label for the x-axis. Default is NULL.
#' @param y_label A string specifying the label for the y-axis. Default is NULL.
Expand All @@ -13,42 +14,80 @@
#'
#' @return A ggplot object.

# Define the function
plot_measures <- function(
data,
measure_names,
date_col = "interval_end",
value_col = "numerator",
measure_col = "measure",
title = NULL,
x_label = NULL,
y_label = NULL,
color_label = NULL) {
color_label = NULL,
axis_x_text_size = 7) {

# Check if the necessary columns exist in the data
if (date_col %in% names(data) == FALSE) {
stop("Data does not have a column with the name '", date_col, "'")
} else if (value_col %in% names(data) == FALSE) {
stop("Data does not have a column with the name '", value_col, "'")
} else if (measure_col %in% names(data) == FALSE) {
stop("Data does not have a column with the name '", measure_col, "'")
}

# Convert column names to symbols
date_sym <- sym(date_col)
value_sym <- sym(value_col)
measure_sym <- sym(measure_col)

# Ensure the date column is of Date type
data <- data %>%
mutate(!!date_sym := as.Date(!!date_sym))

# Filter measures column for user-specified measure names
data <- data %>%
filter(!!measure_sym %in% measure_names)

# Create plot
plot1 <- ggplot(
data,
aes(
x = {{date_col}},
y = {{value_col}},
color = {{measure_col}},
group = {{measure_col}}
x = !!date_sym,
y = !!value_sym,
color = !!measure_sym,
group = !!measure_sym
)
) +
geom_line() +
labs(
title = title,
x = x_label,
y = y_label,
color = "Condition"
color = color_label
) +
scale_y_continuous(
limits = c(0, NA),
) +
# Setting the minimum y-value
ylim(0, NA) +
# Applying the minimal theme
theme_minimal() +
theme(axis.text.x = element_text(size = axis_x_text_size),
legend.position="bottom",
legend.key.size = unit(0.5, "cm"),
legend.text = element_text(size = 6),
legend.title = element_text(size = 8)) +
guides(
color = guide_legend(nrow = 2) # Adjust number of rows in the legend
) +
geom_vline(
xintercept = lubridate::as_date("2024-02-01"),
linetype = "dotted",
colour = "orange",
linewidth = .7) +
scale_x_date(
date_breaks = "1 month",
date_labels = "%b %Y",
date_breaks = "1 month",
date_labels = "%b %Y"
)

# Return plot

plot1
}
}
23 changes: 0 additions & 23 deletions lib/functions/sketch.R

This file was deleted.

0 comments on commit 7a80e1f

Please sign in to comment.