library(arframe)
library(pharmaverseadam)
library(dplyr, warn.conflicts = FALSE)
library(tidyr)
library(cards)
adsl_saf <- pharmaverseadam::adsl |>
blank_to_na() |>
filter(SAFFL == "Y", TRT01A != "Screen Failure")
# Prior medications: PREFL == "Y", exclude UNCODED
adcm_prior <- pharmaverseadam::adcm |>
blank_to_na() |>
filter(SAFFL == "Y", PREFL == "Y", !is.na(CMCLAS), CMCLAS != "UNCODED")
arm_levels <- c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")
arm_n <- adsl_saf |>
filter(TRT01A %in% arm_levels) |>
count(TRT01A) |> pull(n, name = TRT01A)
arm_n <- arm_n[arm_levels]
N_total <- nrow(adsl_saf)
n_vec <- c(arm_n, Total = N_total)Prior Medication
Summary of Prior Medications by Medication Class and Preferred Name
Setup
See Prerequisites for installation instructions.
Data Preparation
n_pct <- function(n, denom) sprintf("%d (%.1f)", n, n / denom * 100)
# ── Overall row ──
any_prior_arm <- adcm_prior |>
distinct(USUBJID, TRT01A) |>
count(TRT01A) |>
filter(TRT01A %in% arm_levels) |>
mutate(value = mapply(n_pct, n, arm_n[TRT01A])) |>
select(TRT01A, value) |>
pivot_wider(names_from = TRT01A, values_from = value)
any_prior_total <- n_distinct(adcm_prior$USUBJID)
any_prior_row <- bind_cols(
tibble(cls = "ANY PRIOR MEDICATION", drug = "ANY PRIOR MEDICATION",
row_type = "overall"),
any_prior_arm,
tibble(Total = n_pct(any_prior_total, N_total))
)
# ── Class-level (CMCLAS) ──
cls_arm <- adcm_prior |>
distinct(USUBJID, TRT01A, CMCLAS) |>
count(TRT01A, CMCLAS) |>
filter(TRT01A %in% arm_levels) |>
mutate(value = mapply(n_pct, n, arm_n[TRT01A])) |>
select(TRT01A, CMCLAS, value) |>
pivot_wider(names_from = TRT01A, values_from = value)
cls_total <- adcm_prior |>
distinct(USUBJID, CMCLAS) |>
count(CMCLAS) |>
mutate(Total = n_pct(n, N_total)) |>
select(CMCLAS, Total)
cls_wide <- left_join(cls_arm, cls_total, by = "CMCLAS") |>
mutate(cls = CMCLAS, drug = CMCLAS, row_type = "class", .before = 1) |>
select(-CMCLAS)
# ── Drug-level (CMDECOD) ──
drug_arm <- adcm_prior |>
distinct(USUBJID, TRT01A, CMCLAS, CMDECOD) |>
count(TRT01A, CMCLAS, CMDECOD) |>
filter(TRT01A %in% arm_levels) |>
mutate(value = mapply(n_pct, n, arm_n[TRT01A])) |>
select(TRT01A, CMCLAS, CMDECOD, value) |>
pivot_wider(names_from = TRT01A, values_from = value)
drug_total <- adcm_prior |>
distinct(USUBJID, CMCLAS, CMDECOD) |>
count(CMCLAS, CMDECOD) |>
mutate(Total = n_pct(n, N_total)) |>
select(CMCLAS, CMDECOD, Total)
drug_wide <- left_join(drug_arm, drug_total, by = c("CMCLAS", "CMDECOD")) |>
mutate(cls = CMCLAS, drug = CMDECOD, row_type = "drug", .before = 1) |>
select(-CMCLAS, -CMDECOD)
# ── Sort: class alphabetical, drugs within class by frequency ──
cls_order <- sort(unique(cls_wide$cls))
prior_med_wide <- bind_rows(
any_prior_row,
bind_rows(lapply(cls_order, function(c) {
bind_rows(
filter(cls_wide, cls == c),
filter(drug_wide, cls == c) |>
left_join(
adcm_prior |> distinct(USUBJID, CMCLAS, CMDECOD) |>
count(CMCLAS, CMDECOD, name = "drug_n"),
by = c("cls" = "CMCLAS", "drug" = "CMDECOD")
) |> arrange(desc(drug_n)) |> select(-drug_n)
)
}))
) |>
mutate(across(where(is.character) & !c(cls, drug, row_type),
~ replace_na(.x, "0 (0.0)")))prior_ard <- ard_stack_hierarchical(
data = adcm_prior,
variables = c(CMCLAS, CMDECOD),
by = TRT01A,
denominator = adsl_saf,
id = USUBJID,
overall = TRUE,
over_variables = TRUE
) |>
sort_ard_hierarchical(sort = "descending")
prior_med_cards <- fr_wide_ard(
prior_ard,
statistic = "{n} ({p}%)",
decimals = c(p = 1),
label = c(
"..ard_hierarchical_overall.." = "ANY PRIOR MEDICATION",
CMCLAS = "Medication Class",
CMDECOD = "Preferred Name"
)
)arframe Pipeline
prior_med_wide |>
fr_table() |>
fr_titles(
"Table 14.1.8",
"Summary of Prior Medications",
"by Medication Class and Preferred Name",
"Safety Population"
) |>
fr_cols(
cls = fr_col(visible = FALSE),
drug = fr_col("Medication Class\n Preferred Name", width = 3.5),
row_type = fr_col(visible = FALSE),
!!!setNames(
lapply(arm_levels, function(a) fr_col(a, align = "decimal")),
arm_levels
),
Total = fr_col("Total", align = "decimal"),
.n = n_vec
) |>
fr_header(bold = TRUE, align = "center") |>
fr_rows(group_by = "cls", indent_by = "drug") |>
fr_styles(
fr_row_style(rows = fr_rows_matches("row_type", value = "class"), bold = TRUE),
fr_row_style(rows = fr_rows_matches("row_type", value = "overall"), bold = TRUE)
) |>
fr_footnotes(
"Prior medication: any medication started before first dose of study drug.",
"Subjects counted once per medication class and once per preferred name.",
"Percentages based on N per treatment arm (Safety Population).",
"UNCODED medications excluded."
)Rendered Table
Table 14.1.8
Summary of Prior Medications
by Medication Class and Preferred Name
Safety Population
| Medication Class Preferred Name | Placebo (N=86) | Xanomeline High Dose (N=72) | Xanomeline Low Dose (N=96) | Total (N=254) |
|---|---|---|---|---|
| ANY PRIOR MEDICATION | 38 (44.2) | 18 (25.0) | 35 (36.5) | 91 (35.8) |
| ALIMENTARY TRACT AND METABOLISM | 10 (11.6) | 8 (11.1) | 10 (10.4) | 28 (11.0) |
| CALCIUM | 7 ( 8.1) | 3 ( 4.2) | 6 ( 6.2) | 16 ( 6.3) |
| NIZATIDINE | 1 ( 1.2) | 4 ( 5.6) | 0 | 5 ( 2.0) |
| METFORMIN HYDROCHLORIDE | 1 ( 1.2) | 0 | 1 ( 1.0) | 2 ( 0.8) |
| SIMETICONE | 0 | 0 | 2 ( 2.1) | 2 ( 0.8) |
| ALGELDRATE | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
| CALCIUM CARBONATE | 0 | 1 ( 1.4) | 0 | 1 ( 0.4) |
| LOPERAMIDE HYDROCHLORIDE | 0 | 0 | 1 ( 1.0) | 1 ( 0.4) |
| ANTINEOPLASTIC AND IMMUNOMODULATING AGENTS | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
| LEUPRORELIN ACETATE | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
| BLOOD AND BLOOD FORMING ORGANS | 0 | 0 | 1 ( 1.0) | 1 ( 0.4) |
| FERROUS SULFATE | 0 | 0 | 1 ( 1.0) | 1 ( 0.4) |
| CARDIOVASCULAR SYSTEM | 9 (10.5) | 3 ( 4.2) | 11 (11.5) | 23 ( 9.1) |
| AMLODIPINE | 5 ( 5.8) | 2 ( 2.8) | 1 ( 1.0) | 8 ( 3.1) |
| DIGOXIN | 0 | 1 ( 1.4) | 4 ( 4.2) | 5 ( 2.0) |
| FUROSEMIDE | 1 ( 1.2) | 0 | 2 ( 2.1) | 3 ( 1.2) |
| DOXAZOSIN MESILATE | 1 ( 1.2) | 0 | 1 ( 1.0) | 2 ( 0.8) |
| NIFEDIPINE | 2 ( 2.3) | 0 | 0 | 2 ( 0.8) |
| FLUVASTATIN | 0 | 0 | 2 ( 2.1) | 2 ( 0.8) |
| FELODIPINE | 0 | 0 | 1 ( 1.0) | 1 ( 0.4) |
| LOSARTAN POTASSIUM | 0 | 0 | 1 ( 1.0) | 1 ( 0.4) |
| GENITO URINARY SYSTEM AND SEX HORMONES | 6 ( 7.0) | 4 ( 5.6) | 10 (10.4) | 20 ( 7.9) |
| ESTROGENS CONJUGATED | 6 ( 7.0) | 4 ( 5.6) | 10 (10.4) | 20 ( 7.9) |
| NERVOUS SYSTEM | 20 (23.3) | 5 ( 6.9) | 10 (10.4) | 35 (13.8) |
| ACETYLSALICYLIC ACID | 19 (22.1) | 5 ( 6.9) | 10 (10.4) | 34 (13.4) |
| ALPRAZOLAM | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
| SUMATRIPTAN | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
| RESPIRATORY SYSTEM | 3 ( 3.5) | 3 ( 4.2) | 0 | 6 ( 2.4) |
| NAPROXEN SODIUM | 1 ( 1.2) | 3 ( 4.2) | 0 | 4 ( 1.6) |
| SALBUTAMOL SULFATE | 2 ( 2.3) | 0 | 0 | 2 ( 0.8) |
| IPRATROPIUM BROMIDE | 1 ( 1.2) | 0 | 0 | 1 ( 0.4) |
Prior medication: any medication started before first dose of study drug.
Subjects counted once per medication class and once per preferred name.
Percentages based on N per treatment arm (Safety Population).
UNCODED medications excluded.
/opt/quarto/share/rmd/rmd.R
01APR2026 09:54:23