From d8bed2fcb9690e12efd62fadfa2d7f7be2486468 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Mon, 19 Jan 2026 17:20:11 -0600 Subject: [PATCH 01/14] #292 add ader template --- inst/templates/ad_ader.R | 190 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 inst/templates/ad_ader.R diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R new file mode 100644 index 00000000..9aedb84d --- /dev/null +++ b/inst/templates/ad_ader.R @@ -0,0 +1,190 @@ +# Name: ADER +# +# Label: Exposure Response Data +# +# Input: adsl, adrs, tte_source objects +library(admiral) +library(admiralonco) +# pharmaverseadam contains example datasets generated from the CDISC pilot +# project SDTM ran through admiral templates +library(pharmaverseadam) +library(dplyr) +library(lubridate) +library(stringr) + +# Load source datasets ---- + +# Use e.g. haven::read_sas to read in .sas7bdat, or other suitable functions +# as needed and assign to the variables below. +# For illustration purposes read in admiral test data + +adtte <- pharmaverseadam::adtte_onco +adrs <- pharmaverseadam::adrs_onco +adsl <- pharmaverseadam::adsl +adlb <- pharmaverseadam::adlb +advs <- pharmaverseadam::advs +adex <- pharmaverseadam::adex %>% + filter(PARCAT1 == "INDIVIDUAL") + +# Derivations ---- + +# For ADTTE censor variables add "IND" to PARAMCD +adttei <- adtte %>% + mutate(PARAMCD = paste0(PARAMCD, "IND")) + +ader_tte <- adsl %>% + select(!!!get_admiral_option("subject_keys")) %>% + # Create OS and PFS variables from ADTTE + derive_vars_transposed( + dataset_merge = adtte, + by_vars = get_admiral_option("subject_keys"), + key_var = PARAMCD, + value_var = AVAL + ) %>% + # Create OS and PFS censor variables + derive_vars_transposed( + dataset_merge = adttei, + by_vars = get_admiral_option("subject_keys"), + key_var = PARAMCD, + value_var = CNSR + ) + +# Add response date to ADSL for duration of response calculation +ader_bor <- ader_tte %>% + derive_vars_merged( + dataset_add = adrs, + filter_add = PARAMCD == "BOR" & ANL01FL == "Y", + by_vars = get_admiral_option("subject_keys"), + new_vars = exprs(BOR = AVAL) + ) + +ader_aseq <- ader_bor %>% + derive_var_obs_number( + by_vars = get_admiral_option("subject_keys"), + check_type = "error" + ) + +#---- Derive Covariates ---- +# Include numeric values for STUDYIDN, USUBJIDN, SEXN, RACEN etc. + +covar <- adsl %>% + derive_vars_merged( + dataset_add = country_code_lookup, + new_vars = exprs(COUNTRYN = country_number, COUNTRYL = country_name), + by_vars = exprs(COUNTRY = country_code), + ) %>% + mutate( + STUDYIDN = as.numeric(word(USUBJID, 1, sep = fixed("-"))), + SITEIDN = as.numeric(word(USUBJID, 2, sep = fixed("-"))), + USUBJIDN = as.numeric(word(USUBJID, 3, sep = fixed("-"))), + SUBJIDN = as.numeric(SUBJID), + SEXN = case_when( + SEX == "M" ~ 1, + SEX == "F" ~ 2, + TRUE ~ 3 + ), + RACEN = case_when( + RACE == "AMERICAN INDIAN OR ALASKA NATIVE" ~ 1, + RACE == "ASIAN" ~ 2, + RACE == "BLACK OR AFRICAN AMERICAN" ~ 3, + RACE == "NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" ~ 4, + RACE == "WHITE" ~ 5, + TRUE ~ 6 + ), + ETHNICN = case_when( + ETHNIC == "HISPANIC OR LATINO" ~ 1, + ETHNIC == "NOT HISPANIC OR LATINO" ~ 2, + TRUE ~ 3 + ), + ARMN = case_when( + ARM == "Placebo" ~ 0, + ARM == "Xanomeline Low Dose" ~ 1, + ARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + ACTARMN = case_when( + ACTARM == "Placebo" ~ 0, + ACTARM == "Xanomeline Low Dose" ~ 1, + ACTARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + COHORT = ARMN, + COHORTC = ARM, + ROUTE = unique(adex$EXROUTE), + ROUTEN = case_when( + ROUTE == "TRANSDERMAL" ~ 3, + TRUE ~ NA_real_ + ), + FORM = unique(adex$EXDOSFRM), + FORMN = case_when( + FORM == "PATCH" ~ 3, + TRUE ~ 4 + ) + ) %>% + select( + STUDYID, STUDYIDN, SITEID, SITEIDN, USUBJID, USUBJIDN, + SUBJID, SUBJIDN, AGE, SEX, SEXN, COHORT, COHORTC, ROUTE, ROUTEN, + RACE, RACEN, ETHNIC, ETHNICN, FORM, FORMN, COUNTRY, COUNTRYN, COUNTRYL + ) + +#---- Derive additional baselines from VS and LB ---- + +labsbl <- adlb %>% + filter(ABLFL == "Y" & PARAMCD %in% c("CREAT", "ALT", "AST", "BILI")) %>% + mutate(PARAMCDB = paste0(PARAMCD, "BL")) %>% + select(STUDYID, USUBJID, PARAMCDB, AVAL) + +covar_vslb <- covar %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "HEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(HTBL = AVAL) + ) %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "WEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(WTBL = AVAL) + ) %>% + derive_vars_transposed( + dataset_merge = labsbl, + by_vars = exprs(STUDYID, USUBJID), + key_var = PARAMCDB, + value_var = AVAL + ) %>% + mutate( + BMIBL = compute_bmi(height = HTBL, weight = WTBL), + BSABL = compute_bsa( + height = HTBL, + weight = HTBL, + method = "Mosteller" + ), + CRCLBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, + method = "CRCL" + ), + EGFRBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, + method = "CKD-EPI" + ) + ) %>% + rename(TBILBL = BILIBL) + +# Combine covariates with ADER data + +ader <- ader_aseq %>% + derive_vars_merged( + dataset_add = covar_vslb, + by_vars = exprs(STUDYID, USUBJID) + ) + +# Save output ---- + +# Change to whichever directory you want to save the dataset in +dir <- tools::R_user_dir("admiralonco_templates_data", which = "cache") +if (!file.exists(dir)) { + # Create the folder + dir.create(dir, recursive = TRUE, showWarnings = FALSE) +} +save(ader, file = file.path(dir, "ader.rda"), compress = "bzip2") From 4320ff5f3d9093972e41d689f4aaef278afac48e Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Tue, 20 Jan 2026 09:06:02 -0600 Subject: [PATCH 02/14] #292 add BORC --- inst/templates/ad_ader.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 9aedb84d..f8a8f4bd 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -55,7 +55,7 @@ ader_bor <- ader_tte %>% dataset_add = adrs, filter_add = PARAMCD == "BOR" & ANL01FL == "Y", by_vars = get_admiral_option("subject_keys"), - new_vars = exprs(BOR = AVAL) + new_vars = exprs(BOR = AVAL, BORC = AVALC) ) ader_aseq <- ader_bor %>% From cfbde042c3d6589f4e94edc96725078bbb5afcf1 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Tue, 20 Jan 2026 10:41:29 -0600 Subject: [PATCH 03/14] #292 source adrs from data? --- inst/templates/ad_ader.R | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index f8a8f4bd..aa1e21f3 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -18,9 +18,13 @@ library(stringr) # as needed and assign to the variables below. # For illustration purposes read in admiral test data +data("admiral_adsl") +data("admiral_adrs") + +adsl <- admiral_adsl +adrs <- admiral_adrs + adtte <- pharmaverseadam::adtte_onco -adrs <- pharmaverseadam::adrs_onco -adsl <- pharmaverseadam::adsl adlb <- pharmaverseadam::adlb advs <- pharmaverseadam::advs adex <- pharmaverseadam::adex %>% From ad702c08ca3d4d1ed68bd455ab3a348580647be6 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 14:36:00 -0600 Subject: [PATCH 04/14] Update inst/templates/ad_ader.R Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- inst/templates/ad_ader.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index aa1e21f3..59f081cd 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -114,12 +114,12 @@ covar <- adsl %>% ), COHORT = ARMN, COHORTC = ARM, - ROUTE = unique(adex$EXROUTE), + ROUTE = unique(adex$EXROUTE)[1], ROUTEN = case_when( ROUTE == "TRANSDERMAL" ~ 3, TRUE ~ NA_real_ ), - FORM = unique(adex$EXDOSFRM), + FORM = unique(adex$EXDOSFRM)[1], FORMN = case_when( FORM == "PATCH" ~ 3, TRUE ~ 4 From 17d2d4de5ea62c961fd21aeb0c10feb0d0b280ed Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 14:36:08 -0600 Subject: [PATCH 05/14] Update inst/templates/ad_ader.R Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- inst/templates/ad_ader.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 59f081cd..9c541a0b 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -2,7 +2,7 @@ # # Label: Exposure Response Data # -# Input: adsl, adrs, tte_source objects +# Input: adsl, adrs, adtte, adlb, advs, adex library(admiral) library(admiralonco) # pharmaverseadam contains example datasets generated from the CDISC pilot From 09605a0eff1faf7769690871266399dcf0288e9e Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 14:37:01 -0600 Subject: [PATCH 06/14] Update inst/templates/ad_ader.R Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- inst/templates/ad_ader.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 9c541a0b..926cbca5 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -161,7 +161,7 @@ covar_vslb <- covar %>% BMIBL = compute_bmi(height = HTBL, weight = WTBL), BSABL = compute_bsa( height = HTBL, - weight = HTBL, + weight = WTBL, method = "Mosteller" ), CRCLBL = compute_egfr( From 2882a9336d2e1c1bba1a15d190d3e05119dd3272 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 14:37:24 -0600 Subject: [PATCH 07/14] Update inst/templates/ad_ader.R Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- inst/templates/ad_ader.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 926cbca5..a276e301 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -75,7 +75,7 @@ covar <- adsl %>% derive_vars_merged( dataset_add = country_code_lookup, new_vars = exprs(COUNTRYN = country_number, COUNTRYL = country_name), - by_vars = exprs(COUNTRY = country_code), + by_vars = exprs(COUNTRY = country_code) ) %>% mutate( STUDYIDN = as.numeric(word(USUBJID, 1, sep = fixed("-"))), From be0964e7bb9036b3d47b2d62fb95c738ca9f89c1 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 14:37:58 -0600 Subject: [PATCH 08/14] Update inst/templates/ad_ader.R Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- inst/templates/ad_ader.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index a276e301..71017bc0 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -53,7 +53,7 @@ ader_tte <- adsl %>% value_var = CNSR ) -# Add response date to ADSL for duration of response calculation +# Derive Best Overall Response (BOR) variables from ADRS ader_bor <- ader_tte %>% derive_vars_merged( dataset_add = adrs, From 5a2cb5c24c05c9c5c9e2d16efb1d0e0d62802e87 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 28 Jan 2026 15:11:34 -0600 Subject: [PATCH 09/14] #292 update from copilot comments --- inst/templates/ad_ader.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 71017bc0..c322523d 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -20,6 +20,7 @@ library(stringr) data("admiral_adsl") data("admiral_adrs") +data("country_code_lookup") adsl <- admiral_adsl adrs <- admiral_adrs @@ -68,7 +69,7 @@ ader_aseq <- ader_bor %>% check_type = "error" ) -#---- Derive Covariates ---- +# ---- Derive Covariates ---- # Include numeric values for STUDYIDN, USUBJIDN, SEXN, RACEN etc. covar <- adsl %>% @@ -131,7 +132,7 @@ covar <- adsl %>% RACE, RACEN, ETHNIC, ETHNICN, FORM, FORMN, COUNTRY, COUNTRYN, COUNTRYL ) -#---- Derive additional baselines from VS and LB ---- +# ---- Derive additional baselines from ADVS and ADLB ---- labsbl <- adlb %>% filter(ABLFL == "Y" & PARAMCD %in% c("CREAT", "ALT", "AST", "BILI")) %>% From 1023bdf788bd751dfce6923b7c0e1a550dc354f6 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 4 Feb 2026 10:34:23 -0600 Subject: [PATCH 10/14] #292 add exposure metrics from adpp --- inst/templates/ad_ader.R | 20 +++++++++++++++++++- inst/templates/ad_adtte.R | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index c322523d..75586827 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -31,6 +31,9 @@ advs <- pharmaverseadam::advs adex <- pharmaverseadam::adex %>% filter(PARCAT1 == "INDIVIDUAL") +adpp <- pharmaverseadam::adpp + + # Derivations ---- # For ADTTE censor variables add "IND" to PARAMCD @@ -63,7 +66,21 @@ ader_bor <- ader_tte %>% new_vars = exprs(BOR = AVAL, BORC = AVALC) ) -ader_aseq <- ader_bor %>% +# Add exposure metrics + +ader_auc <- ader_bor %>% + derive_vars_transposed( + dataset_merge = adpp, + filter = PARAMCD %in% c("AUCLST", "CMAX"), + by_vars = get_admiral_option("subject_keys"), + key_var = PARAMCD, + value_var = AVAL + ) %>% + rename(AUCSS = AUCLST, CMAXSS = CMAX) + +# Add Sequence number + +ader_aseq <- ader_auc %>% derive_var_obs_number( by_vars = get_admiral_option("subject_keys"), check_type = "error" @@ -193,3 +210,4 @@ if (!file.exists(dir)) { dir.create(dir, recursive = TRUE, showWarnings = FALSE) } save(ader, file = file.path(dir, "ader.rda"), compress = "bzip2") + diff --git a/inst/templates/ad_adtte.R b/inst/templates/ad_adtte.R index 8b4873d5..6d41b230 100644 --- a/inst/templates/ad_adtte.R +++ b/inst/templates/ad_adtte.R @@ -7,7 +7,7 @@ library(admiral) library(admiralonco) # pharmaverseadam contains example datasets generated from the CDISC pilot # project SDTM ran through admiral templates -library(pharmaverseadam) +#library(pharmaverseadam) library(dplyr) library(lubridate) From b520f0f29fd7f746d1ae597595a1f94af6d32bfe Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 4 Feb 2026 10:57:30 -0600 Subject: [PATCH 11/14] #292 add adee --- inst/templates/ad_adee.R | 249 ++++++++++++++++++++++++++++++++++++++ inst/templates/ad_ader.R | 1 - inst/templates/ad_adtte.R | 2 +- 3 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 inst/templates/ad_adee.R diff --git a/inst/templates/ad_adee.R b/inst/templates/ad_adee.R new file mode 100644 index 00000000..da57a758 --- /dev/null +++ b/inst/templates/ad_adee.R @@ -0,0 +1,249 @@ +# Name: ADEE +# +# Label: Exposure Response Data +# +# Input: adsl, adrs, adtte, adlb, advs, adex, adpp +# Load required packages +library(admiral) +library(admiralonco) +# pharmaverseadam contains example datasets generated from the CDISC pilot +# project SDTM ran through admiral templates +library(pharmaverseadam) +library(dplyr) +library(lubridate) +library(stringr) + +# Load source datasets ---- + +# Use e.g. haven::read_sas to read in .sas7bdat, or other suitable functions +# as needed and assign to the variables below. +# For illustration purposes read in admiral test data + +adsl <- pharmaverseadam::adsl +adtte <- pharmaverseadam::adtte_onco +adlb <- pharmaverseadam::adlb +advs <- pharmaverseadam::advs +adpp <- pharmaverseadam::adpp + +# ---- Prepare adsl - add derived variables + +# Ensure TRT01P/TRT01A exist +if (!"TRT01P" %in% names(adsl)) { + adsl <- adsl %>% mutate(TRT01P = ARM) +} +if (!"TRT01A" %in% names(adsl)) { + adsl <- adsl %>% mutate(TRT01A = ACTARM) +} + +# Create numeric treatment variables +adsl <- adsl %>% + mutate( + TRT01PN = case_when( + TRT01P == "Placebo" ~ 0, + TRT01P == "Xanomeline Low Dose" ~ 1, + TRT01P == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + TRT01AN = case_when( + TRT01A == "Placebo" ~ 0, + TRT01A == "Xanomeline Low Dose" ~ 1, + TRT01A == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ) + ) + +# Ensure PARAMN exists in ADTTE +if (!"PARAMN" %in% names(adtte)) { + adtte <- adtte %>% + mutate( + PARAMN = case_when( + PARAMCD == "PFS" ~ 1, + PARAMCD == "OS" ~ 2, + PARAMCD == "TTP" ~ 3, + PARAMCD == "TTNT" ~ 4, + TRUE ~ 99 + ) + ) +} + +# ---- Derive Baseline Covariates + +## Numeric identifiers and demographics ---- + +adsl_cov <- adsl %>% + mutate( + # Study identifiers (numeric) + STUDYIDN = as.numeric(word(USUBJID, 1, sep = fixed("-"))), + SITEIDN = as.numeric(word(USUBJID, 2, sep = fixed("-"))), + USUBJIDN = as.numeric(word(USUBJID, 3, sep = fixed("-"))), + SUBJIDN = as.numeric(SUBJID), + + # Demographics (numeric) + SEXN = case_when(SEX == "M" ~ 1, SEX == "F" ~ 2, TRUE ~ 3), + RACEN = case_when( + RACE == "AMERICAN INDIAN OR ALASKA NATIVE" ~ 1, + RACE == "ASIAN" ~ 2, + RACE == "BLACK OR AFRICAN AMERICAN" ~ 3, + RACE == "NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" ~ 4, + RACE == "WHITE" ~ 5, + TRUE ~ 6 + ), + ETHNICN = case_when( + ETHNIC == "HISPANIC OR LATINO" ~ 1, + ETHNIC == "NOT HISPANIC OR LATINO" ~ 2, + TRUE ~ 3 + ), + + # Age groups + AGEGR1 = case_when( + AGE < 65 ~ "<65", + AGE >= 65 & AGE < 75 ~ "65-75", + AGE >= 75 ~ ">75", + TRUE ~ NA_character_ + ), + AGEGR1N = case_when( + AGE < 65 ~ 1, + AGE >= 65 & AGE < 75 ~ 2, + AGE >= 75 ~ 3, + TRUE ~ NA_real_ + ), + + # Treatment (numeric) + ARMN = case_when( + ARM == "Placebo" ~ 0, + ARM == "Xanomeline Low Dose" ~ 1, + ARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + ACTARMN = case_when( + ACTARM == "Placebo" ~ 0, + ACTARM == "Xanomeline Low Dose" ~ 1, + ACTARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ) + ) + +## Add baseline vitals ---- + +adsl_vs <- adsl_cov %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "HEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(HTBL = AVAL) + ) %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "WEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(WTBL = AVAL) + ) %>% + mutate( + BMIBL = compute_bmi(height = HTBL, weight = WTBL), + BSABL = compute_bsa(height = HTBL, weight = WTBL, method = "Mosteller"), + WTBLGR1 = case_when( + WTBL < 70 ~ "<70 kg", + WTBL >= 70 ~ ">=70 kg", + TRUE ~ NA_character_ + ) + ) + +## Add baseline labs ---- + +labs_bl <- adlb %>% + filter(ABLFL == "Y" & PARAMCD %in% c("CREAT", "ALT", "AST", "BILI", "ALB")) %>% + mutate(PARAMCDB = paste0(PARAMCD, "BL")) %>% + select(STUDYID, USUBJID, PARAMCDB, AVAL) + +adsl_vslb <- adsl_vs %>% + derive_vars_transposed( + dataset_merge = labs_bl, + by_vars = exprs(STUDYID, USUBJID), + key_var = PARAMCDB, + value_var = AVAL + ) %>% + mutate( + TBILBL = BILIBL, + CRCLBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, + weight = WTBL, sex = SEX, method = "CRCL" + ), + EGFRBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, + weight = WTBL, sex = SEX, method = "CKD-EPI" + ) + ) %>% + select(-BILIBL) + +# ---- Derive Exposure Metrics + +exposure_final <- adsl_vslb %>% + derive_vars_transposed( + dataset_merge = adpp, + filter = PARAMCD %in% c("AUCLST", "CMAX"), + by_vars = get_admiral_option("subject_keys"), + key_var = PARAMCD, + value_var = AVAL + ) %>% + rename(AUCSS = AUCLST, CMAXSS = CMAX) + +# ---- Create adee base dataset + +# Get variable names from both datasets +adsl_vars <- names(exposure_final) +adtte_vars <- names(adtte) + +# Find common variables +common_vars <- intersect(adsl_vars, adtte_vars) + +# Remove key variables to get variables to drop +vars_to_drop <- setdiff(common_vars, c("STUDYID", "USUBJID")) + +adee_base <- adtte %>% + # Filter to efficacy endpoints + filter(PARAMCD %in% c("OS", "PFS", "TTP", "TTNT")) %>% + # Add derived variables + mutate( + EVENT = 1 - CNSR, + AVALU = if_else(!is.na(AVAL), "DAYS", NA_character_), + ) %>% + # Remove overlapping variables (use clean method) + select(-any_of(vars_to_drop)) %>% + # Merge exposure and covariates + derive_vars_merged( + dataset_add = exposure_final, + by_vars = exprs(STUDYID, USUBJID) + ) + +# ---- Add Anaylsis variables + +adee_prefinal <- adee_base %>% + # Analysis flags + mutate( + ANL01FL = if_else(PARAMCD == "PFS", "Y", ""), + ANL02FL = if_else(PARAMCD == "OS", "Y", ""), + ANL03FL = if_else(PARAMCD == "TTP", "Y", ""), + ANL04FL = if_else(PARAMCD == "TTNT", "Y", "") + ) %>% + # Parameter categories + mutate( + PARCAT1 = "EFFICACY", + PARCAT2 = "TIME TO EVENT" + ) %>% + # Sequence number + derive_var_obs_number( + by_vars = exprs(STUDYID, USUBJID), + order = exprs(PARAMN), + new_var = ASEQ, + check_type = "error" + ) + +# Save output ---- + +# Change to whichever directory you want to save the dataset in +dir <- tools::R_user_dir("admiralonco_templates_data", which = "cache") +if (!file.exists(dir)) { + # Create the folder + dir.create(dir, recursive = TRUE, showWarnings = FALSE) +} +save(adee, file = file.path(dir, "adee.rda"), compress = "bzip2") diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 75586827..9cd5b134 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -210,4 +210,3 @@ if (!file.exists(dir)) { dir.create(dir, recursive = TRUE, showWarnings = FALSE) } save(ader, file = file.path(dir, "ader.rda"), compress = "bzip2") - diff --git a/inst/templates/ad_adtte.R b/inst/templates/ad_adtte.R index 6d41b230..8b4873d5 100644 --- a/inst/templates/ad_adtte.R +++ b/inst/templates/ad_adtte.R @@ -7,7 +7,7 @@ library(admiral) library(admiralonco) # pharmaverseadam contains example datasets generated from the CDISC pilot # project SDTM ran through admiral templates -#library(pharmaverseadam) +library(pharmaverseadam) library(dplyr) library(lubridate) From f0521b86c2447d82516a56d782dd5ab7ff221560 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 4 Feb 2026 11:12:56 -0600 Subject: [PATCH 12/14] #292 update final data --- inst/templates/ad_adee.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/templates/ad_adee.R b/inst/templates/ad_adee.R index da57a758..c5bae6cd 100644 --- a/inst/templates/ad_adee.R +++ b/inst/templates/ad_adee.R @@ -217,7 +217,7 @@ adee_base <- adtte %>% # ---- Add Anaylsis variables -adee_prefinal <- adee_base %>% +adee <- adee_base %>% # Analysis flags mutate( ANL01FL = if_else(PARAMCD == "PFS", "Y", ""), From 78be8430c7f659b174fa6955d72b0c162deebef5 Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Wed, 4 Feb 2026 17:02:39 -0600 Subject: [PATCH 13/14] #292 add exposure tumor response --- inst/templates/ad_adtrr.R | 324 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 inst/templates/ad_adtrr.R diff --git a/inst/templates/ad_adtrr.R b/inst/templates/ad_adtrr.R new file mode 100644 index 00000000..f8129bf1 --- /dev/null +++ b/inst/templates/ad_adtrr.R @@ -0,0 +1,324 @@ +# Name: ADTRR +# +# Label: Exposure Tumor Response Data +# +# Input: adsl, adtr, adlb, advs, adex, adpp +# Load required packages +library(admiral) +library(admiralonco) +# pharmaverseadam contains example datasets generated from the CDISC pilot +# project SDTM ran through admiral templates +library(pharmaverseadam) +library(dplyr) +library(lubridate) +library(stringr) + +# Load source datasets ---- + +# Use haven::read_sas() or similar to read in production data +# For illustration, using pharmaverseadam example data +library(pharmaverseadam) + +adsl <- pharmaverseadam::adsl +adtr <- pharmaverseadam::adtr_onco # Has tumor measurements +adrs <- pharmaverseadam::adrs_onco # Has response evaluations +adlb <- pharmaverseadam::adlb +advs <- pharmaverseadam::advs + +# ---- Prepare adsl - add derived variables + +# Ensure TRT01P/TRT01A exist +if (!"TRT01P" %in% names(adsl)) { + adsl <- adsl %>% mutate(TRT01P = ARM) +} +if (!"TRT01A" %in% names(adsl)) { + adsl <- adsl %>% mutate(TRT01A = ACTARM) +} + +# Create numeric treatment variables +adsl <- adsl %>% + mutate( + TRT01PN = case_when( + TRT01P == "Placebo" ~ 0, + TRT01P == "Xanomeline Low Dose" ~ 1, + TRT01P == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + TRT01AN = case_when( + TRT01A == "Placebo" ~ 0, + TRT01A == "Xanomeline Low Dose" ~ 1, + TRT01A == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ) + ) + +# ---- Derive Baseline Covariates + +## Numeric identifiers and demographics ---- + +adsl_cov <- adsl %>% + filter(SAFFL == "Y") %>% + mutate( + # Study identifiers (numeric) + STUDYIDN = as.numeric(word(USUBJID, 1, sep = fixed("-"))), + SITEIDN = as.numeric(word(USUBJID, 2, sep = fixed("-"))), + USUBJIDN = as.numeric(word(USUBJID, 3, sep = fixed("-"))), + SUBJIDN = as.numeric(SUBJID), + + # Demographics (numeric) + SEXN = case_when(SEX == "M" ~ 1, SEX == "F" ~ 2, TRUE ~ 3), + RACEN = case_when( + RACE == "AMERICAN INDIAN OR ALASKA NATIVE" ~ 1, + RACE == "ASIAN" ~ 2, + RACE == "BLACK OR AFRICAN AMERICAN" ~ 3, + RACE == "NATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER" ~ 4, + RACE == "WHITE" ~ 5, + TRUE ~ 6 + ), + ETHNICN = case_when( + ETHNIC == "HISPANIC OR LATINO" ~ 1, + ETHNIC == "NOT HISPANIC OR LATINO" ~ 2, + TRUE ~ 3 + ), + + # Age groups + AGEGR1 = case_when( + AGE < 65 ~ "<65", + AGE >= 65 & AGE < 75 ~ "65-75", + AGE >= 75 ~ ">75", + TRUE ~ NA_character_ + ), + AGEGR1N = case_when( + AGE < 65 ~ 1, + AGE >= 65 & AGE < 75 ~ 2, + AGE >= 75 ~ 3, + TRUE ~ NA_real_ + ), + + # Treatment (numeric) + ARMN = case_when( + ARM == "Placebo" ~ 0, + ARM == "Xanomeline Low Dose" ~ 1, + ARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ), + ACTARMN = case_when( + ACTARM == "Placebo" ~ 0, + ACTARM == "Xanomeline Low Dose" ~ 1, + ACTARM == "Xanomeline High Dose" ~ 2, + TRUE ~ 3 + ) + ) + +## Add baseline vitals ---- + +adsl_vs <- adsl_cov %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "HEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(HTBL = AVAL) + ) %>% + derive_vars_merged( + dataset_add = advs, + filter_add = PARAMCD == "WEIGHT" & ABLFL == "Y", + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(WTBL = AVAL) + ) %>% + mutate( + BMIBL = compute_bmi(height = HTBL, weight = WTBL), + BSABL = compute_bsa(height = HTBL, weight = WTBL, method = "Mosteller"), + WTBLGR1 = case_when( + WTBL < 70 ~ "<70 kg", + WTBL >= 70 ~ ">=70 kg", + TRUE ~ NA_character_ + ) + ) + +## Add baseline labs ---- + +labs_bl <- adlb %>% + filter(ABLFL == "Y" & PARAMCD %in% c("CREAT", "ALT", "AST", "BILI", "ALB")) %>% + mutate(PARAMCDB = paste0(PARAMCD, "BL")) %>% + select(STUDYID, USUBJID, PARAMCDB, AVAL) + +adsl_vslb <- adsl_vs %>% + derive_vars_transposed( + dataset_merge = labs_bl, + by_vars = exprs(STUDYID, USUBJID), + key_var = PARAMCDB, + value_var = AVAL + ) %>% + mutate( + TBILBL = BILIBL, + CRCLBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, + weight = WTBL, sex = SEX, method = "CRCL" + ), + EGFRBL = compute_egfr( + creat = CREATBL, creatu = "SI", age = AGE, + weight = WTBL, sex = SEX, method = "CKD-EPI" + ) + ) %>% + select(-BILIBL) +# ---- Derive Exposure Metrics + +exposure_final <- adsl_vslb %>% + derive_vars_transposed( + dataset_merge = adpp, + filter = PARAMCD %in% c("AUCLST", "CMAX"), + by_vars = get_admiral_option("subject_keys"), + key_var = PARAMCD, + value_var = AVAL + ) %>% + rename(AUCSS = AUCLST, CMAXSS = CMAX) + +# ---- Create tumor size parameter dataset + +# Get variable names for clean dropping +adsl_vars <- names(exposure_final) +adtr_vars <- names(adtr) +common_vars <- intersect(adsl_vars, adtr_vars) +vars_to_drop <- setdiff(common_vars, c("STUDYID", "USUBJID")) + +tsize_final <- adtr %>% + filter(PARAMCD == "SDIAM") %>% + mutate( + PARAMCD = "TSIZE", + PARAM = "Target Lesions Sum of Diameters", + PARAMN = 1 + ) %>% + derive_var_nfrlt( + new_var = NFRLT, + new_var_unit = FRLTU, + out_unit = "HOURS", + visit_day = ADY + ) %>% + select(-any_of(vars_to_drop)) %>% + derive_vars_merged( + dataset_add = exposure_final, + by_vars = exprs(STUDYID, USUBJID) + ) + +# ---- Add BOR from ADRS + +adrs_vars <- names(adrs) +common_vars_adrs <- intersect(adsl_vars, adrs_vars) +vars_to_drop_adrs <- setdiff(common_vars_adrs, c("STUDYID", "USUBJID")) + +bor <- adrs %>% + filter(PARAMCD == "BOR" & SAFFL == "Y") %>% + mutate( + PARAMN = 2, + # Create BORN from AVALC if AVAL doesn't exist + BORN = if ("AVAL" %in% names(.)) { + AVAL + } else { + case_when( + AVALC == "CR" ~ 4, + AVALC == "PR" ~ 3, + AVALC == "SD" ~ 2, + AVALC == "PD" ~ 1, + AVALC == "NE" ~ 0, + TRUE ~ NA_real_ + ) + } + ) %>% + select(-any_of(vars_to_drop_adrs)) %>% + derive_vars_merged( + dataset_add = exposure_final, + by_vars = exprs(STUDYID, USUBJID) + ) + +# ---- Derive Nadir + +# Calculate nadir from TSIZE records +# Keep BASE, CHG, PCHG from the nadir timepoint +nadir <- tsize_final %>% + filter(AVISITN > 0 & !is.na(AVAL)) %>% + group_by(STUDYID, USUBJID) %>% + filter(AVAL == min(AVAL, na.rm = TRUE)) %>% + slice(1) %>% + ungroup() %>% + mutate( + PARAMCD = "NADIR", + PARAM = "Nadir Tumor Size", + PARAMN = 3, + NADIR = AVAL, + NADPCHG = PCHG, # Keep PCHG at nadir + NADVST = AVISIT # Keep visit of nadir + ) + +# ---- Combine parameters + +adtrr_base <- bind_rows( + tsize_final, + bor, + nadir +) %>% + arrange(USUBJID, PARAMN, AVISITN) + +# ---- Add analysis variables + +# Ensure AVALU exists before mutating +if (!"AVALU" %in% names(adtrr_base)) { + adtrr_base <- adtrr_base %>% + mutate(AVALU = NA_character_) +} + +adtrr <- adtrr_base %>% + # Analysis flags + mutate( + # Baseline flag + ABLFL = case_when( + !is.na(ABLFL) ~ ABLFL, + !is.na(AVISITN) & AVISITN == 0 ~ "Y", + TRUE ~ "" + ), + + # Post-baseline flag + ANL01FL = if_else(!is.na(AVISITN) & AVISITN > 0, "Y", ""), + + # Responders (CR or PR) + ANL02FL = if_else(!is.na(AVALC) & AVALC %in% c("CR", "PR"), "Y", ""), + + # Has change from baseline + ANL03FL = if_else(!is.na(PCHG), "Y", "") + ) %>% + # Parameter categories + mutate( + PARCAT1 = "TUMOR RESPONSE", + PARCAT2 = case_when( + PARAMCD == "TSIZE" ~ "MEASUREMENT", + PARAMCD == "BOR" ~ "OVERALL RESPONSE", + PARAMCD == "NADIR" ~ "BEST RESPONSE", + TRUE ~ NA_character_ + ) + ) %>% + # Set AVALU (now guaranteed to exist) + mutate( + AVALU = case_when( + !is.na(AVALU) & AVALU != "" ~ AVALU, # Keep existing non-empty + PARAMCD == "TSIZE" ~ "mm", + PARAMCD == "NADIR" ~ "mm", + TRUE ~ NA_character_ + ) + ) %>% + # Sequence number + derive_var_obs_number( + by_vars = exprs(STUDYID, USUBJID), + order = exprs(PARAMN, AVISITN), + new_var = ASEQ, + check_type = "error" + ) %>% + arrange(USUBJID, PARAMN, AVISITN) + +# Save output ---- + +# Change to whichever directory you want to save the dataset in +dir <- tools::R_user_dir("admiralonco_templates_data", which = "cache") +if (!file.exists(dir)) { + # Create the folder + dir.create(dir, recursive = TRUE, showWarnings = FALSE) +} +save(adtrr, file = file.path(dir, "adtrr.rda"), compress = "bzip2") From 6fa458ccb0364a9f68c61040c4ec95b2c7f0540c Mon Sep 17 00:00:00 2001 From: Jeff Dickinson Date: Thu, 5 Feb 2026 17:01:59 -0600 Subject: [PATCH 14/14] #292 udpate data source --- inst/templates/ad_adee.R | 4 ++-- inst/templates/ad_ader.R | 12 +++--------- inst/templates/ad_adtrr.R | 12 +++++++----- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/inst/templates/ad_adee.R b/inst/templates/ad_adee.R index c5bae6cd..8c4a7980 100644 --- a/inst/templates/ad_adee.R +++ b/inst/templates/ad_adee.R @@ -1,8 +1,8 @@ # Name: ADEE # -# Label: Exposure Response Data +# Label: Exposure Efficacy Response Data # -# Input: adsl, adrs, adtte, adlb, advs, adex, adpp +# Input: adsl, adtte, adlb, advs, adex, adpp # Load required packages library(admiral) library(admiralonco) diff --git a/inst/templates/ad_ader.R b/inst/templates/ad_ader.R index 9cd5b134..e85c4ce0 100644 --- a/inst/templates/ad_ader.R +++ b/inst/templates/ad_ader.R @@ -16,15 +16,10 @@ library(stringr) # Use e.g. haven::read_sas to read in .sas7bdat, or other suitable functions # as needed and assign to the variables below. -# For illustration purposes read in admiral test data - -data("admiral_adsl") -data("admiral_adrs") -data("country_code_lookup") - -adsl <- admiral_adsl -adrs <- admiral_adrs +# For illustration purposes read in data from pharmaverseadam +adsl <- pharmaverseadam::adsl +adrs <- pharmaverseadam::adrs_onco adtte <- pharmaverseadam::adtte_onco adlb <- pharmaverseadam::adlb advs <- pharmaverseadam::advs @@ -33,7 +28,6 @@ adex <- pharmaverseadam::adex %>% adpp <- pharmaverseadam::adpp - # Derivations ---- # For ADTTE censor variables add "IND" to PARAMCD diff --git a/inst/templates/ad_adtrr.R b/inst/templates/ad_adtrr.R index f8129bf1..703f84ab 100644 --- a/inst/templates/ad_adtrr.R +++ b/inst/templates/ad_adtrr.R @@ -15,15 +15,16 @@ library(stringr) # Load source datasets ---- -# Use haven::read_sas() or similar to read in production data -# For illustration, using pharmaverseadam example data -library(pharmaverseadam) +# Use e.g. haven::read_sas to read in .sas7bdat, or other suitable functions +# as needed and assign to the variables below. +# For illustration purposes read in data from pharmaverseadam adsl <- pharmaverseadam::adsl -adtr <- pharmaverseadam::adtr_onco # Has tumor measurements -adrs <- pharmaverseadam::adrs_onco # Has response evaluations +adrs <- pharmaverseadam::adrs_onco +adtr <- pharmaverseadam::adtr_onco adlb <- pharmaverseadam::adlb advs <- pharmaverseadam::advs +adpp <- pharmaverseadam::adpp # ---- Prepare adsl - add derived variables @@ -311,6 +312,7 @@ adtrr <- adtrr_base %>% new_var = ASEQ, check_type = "error" ) %>% + select(-DOMAIN, -all_of(c(starts_with("RS"), starts_with("TR"), starts_with("TU")))) %>% arrange(USUBJID, PARAMN, AVISITN) # Save output ----