Requirements
- Prostate cancer diagnosis with date
- RNA biopsy with date
- Pluvicto with date (using the onco_care_plan table) – generic med
name is lutetium lu 177 vipivotide tetraxetan
- For patients with biopsy post-Pluvicto, please identify patients
that have a regimen that begins between Pluvicto and biopsy, we will
need counts for this in early January Note: for the purposes of the QC,
you can remove all radiotherapy instances; they should not be used to
determine if a regimen is flanking a biopsy
- Number of patients that were previously delivered (this can be found
in docs/Data_Model/legacy_ID_mapping; you can match the ID to the
patients delivered in the prior Prostate intermediate files)
library(tidyverse)
library(data.table)
folder <- "/stash/data/clin/external-collaboration/tempus/P-20251203-0001/delivery_20251205/"
drug_name <- "lutetium lu 177 vipivotide tetraxetan"
# Total Patients
onco_patient <- read_csv(paste0(folder, "/data/Clinical/onco_patient.csv"), show_col_types = FALSE)
patients_all <- onco_patient$patient_id %>% unique
print(paste("Total Number of Patients:", length(patients_all)))
## [1] "Total Number of Patients: 211"
# Patients with a diagnosis date (not a year-only date)
onco_diagnosis <- read_csv(paste0(folder, "/data/Clinical/onco_diagnosis.csv"), show_col_types = FALSE)
patients_diagnosis <- onco_diagnosis %>%
dplyr::filter(grepl("^\\d{4}-\\d{2}-\\d{2}$", initial_diagnosis_date))
rejected_diagnosis <- setdiff(patients_all, patients_diagnosis$patient_id)
print(paste("Patients without a diagnosis full date:", length(rejected_diagnosis)))
## [1] "Patients without a diagnosis full date: 16"
print("List of Patients without a diagnosis full date:")
## [1] "List of Patients without a diagnosis full date:"
df <- onco_diagnosis %>% filter(patient_id %in% rejected_diagnosis) %>% dplyr::select( patient_id, initial_diagnosis_date)
DT::datatable(
df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
)
)
# Patient with a RNA biopsy date (not a year-only date)
onco_meta_biospecimen <- read_csv(paste0(folder, "/data/Group_Level_Molecular//onco_meta_biospecimen.csv"), show_col_types = FALSE)
patients_biopsy <- onco_meta_biospecimen %>%
dplyr::filter(grepl("RNA", polymer_list)) %>%
mutate(RNA_date_check = grepl("^\\d{4}-\\d{2}-\\d{2}$", collection_date))
no_rna_date <- patients_biopsy %>% dplyr::filter(RNA_date_check == FALSE)
rejected_rna_date <- no_rna_date$patient_id
print(paste("Patient without a RNA biopsy full date:", nrow(no_rna_date)))
## [1] "Patient without a RNA biopsy full date: 1"
df <- no_rna_date %>% select(biospecimen_id, patient_id, polymer_list, collection_date)
print("List of Patients without a RNA biopsy full date:")
## [1] "List of Patients without a RNA biopsy full date:"
DT::datatable( df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
)
)
# Pluvicto with date
onco_care_plan <- read_csv(paste0(folder, "/data/Clinical/onco_care_plan.csv"), show_col_types = FALSE)
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
## dat <- vroom(...)
## problems(dat)
drug_date <- onco_care_plan %>%
dplyr::mutate(
drug_has_date = case_when(
grepl(drug_name, agents) & grepl("^\\d{4}-\\d{2}-\\d{2}$", start_date) ~ TRUE,
grepl(drug_name, agents) & !grepl("^\\d{4}-\\d{2}-\\d{2}$", start_date) ~ FALSE,
TRUE ~ NA)
) %>% filter(!is.na(drug_has_date))
rejected_pluvicto_date <- drug_date %>% dplyr::filter(!drug_has_date) %>% pull(patient_id)
output <- drug_date %>% pull(drug_has_date) %>% table(useNA = "always")
print(paste("Pluvicto without a full date:", output[1]))
## [1] "Pluvicto without a full date: 2"
df <- drug_date %>% filter(drug_has_date == FALSE) %>% dplyr::select(care_plan_id, patient_id, agents, start_date)
print("List of Pluvicto without a full date:")
## [1] "List of Pluvicto without a full date:"
DT::datatable( df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
)
)
# - The regimen containing the Pluvicto occurs either directly before or directly
# after the biopsy (it should be within X days, with no other regimens occurring between Pluvicto and biopsy).
# All regimens can be grouped together using care_plan_id
# Extract drug-only regimens
drug_plans <- onco_care_plan %>% dplyr::filter(grepl(drug_name, agents) & !grepl(".*radiotherapy.*", therapy_class, ignore.case = T)) %>%
dplyr::select(care_plan_id, patient_id, regimen_id, agents, start_date_indexed, end_date_indexed)
# Extract non-edrug regimens
non_drug_plans <- onco_care_plan %>% dplyr::filter(!grepl(drug_name, agents) &
!is.na(regimen_id) & !grepl(".*radiotherapy.*", therapy_class, ignore.case = T)) %>%
dplyr::select(care_plan_id, patient_id, regimen_id, agents, start_date_indexed, end_date_indexed)
# Extract relevant biopsis
biopsis <- onco_meta_biospecimen %>%
dplyr::filter(grepl("RNA", polymer_list)) %>%
dplyr::filter(grepl("^\\d{4}-\\d{2}-\\d{2}$", collection_date_indexed)) %>%
dplyr::select(meta_biospecimen_id, patient_id, collection_date_indexed)
# Merge everything together
joined <- full_join(drug_plans, non_drug_plans, by=c( "patient_id"), relationship = "many-to-many") %>%
full_join(biopsis, by=c( "patient_id"), relationship = "many-to-many") %>%
full_join(onco_diagnosis %>% dplyr::select(patient_id, initial_diagnosis_date_indexed), by=c( "patient_id"), relationship = "many-to-many")
# Set some inclusions flags
joined <- joined %>%
# First replace NA date with today date
mutate(
start_date_indexed.x = if_else(is.na(start_date_indexed.x), initial_diagnosis_date_indexed, start_date_indexed.x),
end_date_indexed.x = if_else(is.na(end_date_indexed.x), today(), end_date_indexed.x),
start_date_indexed.y = if_else(is.na(start_date_indexed.y), initial_diagnosis_date_indexed, start_date_indexed.y),
end_date_indexed.y = if_else(is.na(end_date_indexed.y), today(), end_date_indexed.y),
)
# For patients with biopsy post-Pluvicto,
# identify patients that have a regimen that begins between Pluvicto and biopsy
patients_post_drug <- joined %>%
dplyr::select(patient_id, meta_biospecimen_id, regimen_id.x, regimen_id.y, agents.x, agents.y,
start_date_indexed.x, end_date_indexed.x, start_date_indexed.y, end_date_indexed.y,
collection_date_indexed) %>%
dplyr::filter(collection_date_indexed > start_date_indexed.x &
(between(start_date_indexed.y, start_date_indexed.x, collection_date_indexed) |
between(start_date_indexed.y, end_date_indexed.x, collection_date_indexed))
)
df <- patients_post_drug %>% dplyr::select(patient_id, regimen_id.x, regimen_id.y, agents.x, agents.y, start_date_indexed.x, end_date_indexed.x, start_date_indexed.y, end_date_indexed.y, collection_date_indexed)
print(paste("Patients with biopsy post-Pluvicto that have a regimen that begins between Pluvicto and biopsy:", length(df$patient_id %>% unique)))
## [1] "Patients with biopsy post-Pluvicto that have a regimen that begins between Pluvicto and biopsy: 24"
rejected_regimen_between <- df$patient_id %>% unique
print(paste("List of biopsies post-Pluvicto that have a regimen that begins between Pluvicto and the biopsy:"))
## [1] "List of biopsies post-Pluvicto that have a regimen that begins between Pluvicto and the biopsy:"
DT::datatable( df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
)
)
# Number of patients that were previously delivered
legacy_mapping <- read_csv(paste0(folder, "docs/Data_Model/legacy_ID_mapping_20251204.csv"), show_col_types = FALSE)
previous_deliveries <- c(
"/stash/results/dev/teams/trans_epi/prostate/tempus/intermediate_files/delivery_2024_01_16/internal/",
"/stash/results/dev/teams/trans_epi/prostate/tempus/intermediate_files/delivery_2025_08_21/internal/"
)
previous_patients <- unique(unlist(lapply(previous_deliveries,
function(f) read_csv(paste0(f, "demographic.csv"), show_col_types = F)$pt_id)))
previously_delivered <- legacy_mapping %>% dplyr::filter(id_value %in% onco_patient$patient_id & legacy_value %in% previous_patients)
print(paste("Number of patients previously delivered:", nrow(previously_delivered)))
## [1] "Number of patients previously delivered: 3"
print("Patients previously delivered:")
## [1] "Patients previously delivered:"
df <- previously_delivered
DT::datatable( df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
))
rejected_patients <- c(rejected_diagnosis, rejected_rna_date, rejected_pluvicto_date, rejected_regimen_between) %>% unique
print(paste("Total Rejected Patients:", rejected_patients %>% length))
## [1] "Total Rejected Patients: 39"
df <- rejected_patients %>% as.data.frame()
DT::datatable( df,
extensions = "Buttons",
options = list(
pageLength = nrow(df),
scrollX = FALSE,
scrollY = FALSE,
paging = FALSE,
dom = "Bfrtip",
buttons = c("csv")
)
)