arframe TFL Gallery
  1. Tables
  2. Exposure-Adjusted Adverse Events
  • Getting Started
    • Installation

  • Tables
    • Study Conduct
    • Enrollment by Country and Site

    • Study Population
    • Demographics Summary
    • Medical History
    • Prior Medication
    • Disposition Summary
    • Analysis Populations

    • Extent of Exposure
    • Concomitant Medications
    • Extent of Exposure

    • Safety
    • Adverse Events by System Organ Class and Preferred Term
    • AEs Related to Study Drug
    • Common Adverse Events
    • Adverse Events by Grade / Intensity
    • Overall Safety Summary
    • Adverse Events with Event Counts
    • Exposure-Adjusted Adverse Events
    • Adverse Events by Subgroup
    • Serious Adverse Events by SOC and PT
    • AEs Leading to Study Drug Discontinuation
    • Death Summary
    • Vital Signs
    • Laboratory Results - Chemistry
    • Laboratory Shift Table
    • Laboratory Worst Toxicity Grade
    • Laboratory Marked Abnormalities
    • Electrocardiogram Summary

    • Efficacy
    • Time to Event Summary
    • Best Overall Response

  • Listings
    • Adverse Event Listing
    • Demographic Characteristics Listing
    • Medical History Listing
    • Vital Signs Listing
    • Laboratory Test Results Listing
    • Concomitant Medications Listing

  • Figures
    • Kaplan-Meier Plot
    • Swimmer Plot
    • Waterfall Plot

On this page

  • Setup
  • Data Preparation
  • arframe Pipeline
  • Rendered Table
  1. Tables
  2. Exposure-Adjusted Adverse Events

Exposure-Adjusted Adverse Events

Incidence Rate per 100 Patient-Years

Setup

See Prerequisites for installation instructions.

library(arframe)
library(pharmaverseadam)
library(dplyr, warn.conflicts = FALSE)
library(tidyr)

adsl_saf <- pharmaverseadam::adsl |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRT01A != "Screen Failure")

adae_teae <- pharmaverseadam::adae |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRTEMFL == "Y")

# Total study duration per subject from ADEX (TDURD = total duration in days)
adex_tdurd <- pharmaverseadam::adex |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRT01A != "Screen Failure", PARAMCD == "TDURD")

arm_levels <- c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")

Data Preparation

# ── Patient-years per arm: sum subject durations / 365.25 ──
py_by_arm <- adex_tdurd |>
  filter(TRT01A %in% arm_levels) |>
  group_by(TRT01A) |>
  summarise(patient_years = sum(AVAL, na.rm = TRUE) / 365.25, .groups = "drop")

# ── Subjects with at least one TEAE per SOC/PT per arm ──
subj_soc_pt <- adae_teae |>
  distinct(USUBJID, TRT01A, AEBODSYS, AEDECOD) |>
  filter(TRT01A %in% arm_levels) |>
  count(TRT01A, AEBODSYS, AEDECOD, name = "n_subj")

# ── Subjects per SOC (deduplicated) ──
subj_soc <- adae_teae |>
  distinct(USUBJID, TRT01A, AEBODSYS) |>
  filter(TRT01A %in% arm_levels) |>
  count(TRT01A, AEBODSYS, name = "n_subj")

# ── Helper: build n / PY / Rate columns for one dataset ──
build_ea_cols <- function(count_df, by_vars, py_df) {
  count_df |>
    left_join(py_df, by = "TRT01A") |>
    mutate(
      n_col   = as.character(n_subj),
      py_col  = sprintf("%.1f", patient_years),
      rate_col = sprintf("%.2f", n_subj / patient_years * 100)
    ) |>
    select(all_of(by_vars), TRT01A, n_col, py_col, rate_col)
}

# ── SOC-level ──
soc_ea <- build_ea_cols(subj_soc, c("AEBODSYS"), py_by_arm) |>
  pivot_wider(
    names_from  = TRT01A,
    values_from = c(n_col, py_col, rate_col),
    names_glue  = "{TRT01A}__{.value}"
  ) |>
  mutate(
    soc      = AEBODSYS,
    pt       = AEBODSYS,
    row_type = "soc",
    .before  = 1
  ) |>
  select(-AEBODSYS)

# ── PT-level ──
pt_ea <- build_ea_cols(subj_soc_pt, c("AEBODSYS", "AEDECOD"), py_by_arm) |>
  pivot_wider(
    names_from  = TRT01A,
    values_from = c(n_col, py_col, rate_col),
    names_glue  = "{TRT01A}__{.value}"
  ) |>
  mutate(
    soc      = AEBODSYS,
    pt       = AEDECOD,
    row_type = "pt",
    .before  = 1
  ) |>
  select(-AEBODSYS, -AEDECOD)

# ── Sort order: SOC by descending subject count (Placebo + active combined) ──
soc_order <- adae_teae |>
  filter(TRT01A %in% arm_levels) |>
  distinct(USUBJID, AEBODSYS) |>
  count(AEBODSYS, name = "soc_n") |>
  arrange(desc(soc_n)) |>
  pull(AEBODSYS)

pt_order <- adae_teae |>
  filter(TRT01A %in% arm_levels) |>
  distinct(USUBJID, AEBODSYS, AEDECOD) |>
  count(AEBODSYS, AEDECOD, name = "pt_n") |>
  arrange(match(AEBODSYS, soc_order), desc(pt_n))

# ── Interleave SOC rows + PT rows ──
ae_ea_wide <- bind_rows(
  lapply(soc_order, function(s) {
    soc_row <- filter(soc_ea, soc == s)
    pt_rows  <- filter(pt_ea, soc == s) |>
      left_join(
        pt_order |> filter(AEBODSYS == s) |> select(pt = AEDECOD, pt_n),
        by = "pt"
      ) |>
      arrange(desc(pt_n)) |>
      select(-pt_n)
    bind_rows(soc_row, pt_rows)
  })
) |>
  mutate(across(
    where(is.character) & !c(soc, pt, row_type),
    ~ replace_na(.x, "0")
  ))

arframe Pipeline

# Build fr_col() specs in arm-grouped order: n, PY, Rate per arm
arm_col_specs <- unlist(
  lapply(arm_levels, function(a) {
    setNames(
      list(
        fr_col("n",    align = "decimal", width = 0.55),
        fr_col("PY",   align = "decimal", width = 0.65),
        fr_col("Rate", align = "decimal", width = 0.65)
      ),
      c(paste0(a, "__n_col"), paste0(a, "__py_col"), paste0(a, "__rate_col"))
    )
  }),
  recursive = FALSE
)

ae_ea_wide |>
  fr_table() |>
  fr_titles(
    "Exposure-Adjusted Adverse Events",
    "Incidence Rate per 100 Patient-Years",
    "Safety Population"
  ) |>
  fr_cols(
    soc      = fr_col(visible = FALSE),
    pt       = fr_col("System Organ Class\n  Preferred Term", width = 3.0),
    row_type = fr_col(visible = FALSE),
    !!!arm_col_specs
  ) |>
  fr_spans(
    !!!setNames(
      lapply(arm_levels, function(a) {
        c(paste0(a, "__n_col"), paste0(a, "__py_col"), paste0(a, "__rate_col"))
      }),
      arm_levels
    )
  ) |>
  fr_header(bold = TRUE, align = "center") |>
  fr_rows(
    group_by  = "soc",
    indent_by = "pt"
  ) |>
  fr_styles(
    fr_row_style(rows = fr_rows_matches("row_type", value = "soc"), bold = TRUE)
  ) |>
  fr_footnotes(
    "n = number of subjects with at least one event in the category.",
    "PY = patient-years of exposure (total duration in days / 365.25).",
    "Rate = (n / PY) x 100. Subjects counted once per SOC and once per PT.",
    "SOC rows sorted by descending subject frequency across all arms."
  )

Rendered Table

Exposure-Adjusted Adverse Events
Incidence Rate per 100 Patient-Years
Safety Population
Placebo
System Organ Class
Preferred Term
nnnPYPYPYRateRateRate
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS21365134.822.122.660.34162.74225.87
APPLICATION SITE PRURITUS 6212334.822.122.617.24 94.93101.86
APPLICATION SITE ERYTHEMA 3141334.822.122.6 8.62 63.29 57.58
APPLICATION SITE DERMATITIS 5 7 934.822.122.614.37 31.64 39.86
APPLICATION SITE IRRITATION 3 9 934.822.122.6 8.62 40.68 39.86
APPLICATION SITE VESICLES 1 5 534.822.122.6 2.87 22.60 22.14
FATIGUE 1 5 534.822.122.6 2.87 22.60 22.14
OEDEMA PERIPHERAL 2 2 134.822.122.6 5.75 9.04 4.43
CHILLS 1 1 134.822.122.6 2.87 4.52 4.43
PYREXIA 2 0 134.8 0 22.6 5.75 0 4.43
APPLICATION SITE SWELLING 0 2 1 0 22.122.6 0 9.04 4.43
APPLICATION SITE URTICARIA 0 1 2 0 22.122.6 0 4.52 8.86
MALAISE 0 2 1 0 22.122.6 0 9.04 4.43
APPLICATION SITE REACTION 1 1 034.822.1 0 2.87 4.52 0
ASTHENIA 1 0 134.8 0 22.6 2.87 0 4.43
APPLICATION SITE PAIN 0 2 0 0 22.1 0 0 9.04 0
APPLICATION SITE PERSPIRATION 0 2 0 0 22.1 0 0 9.04 0
CHEST DISCOMFORT 0 1 1 0 22.122.6 0 4.52 4.43
CHEST PAIN 0 2 0 0 22.1 0 0 9.04 0
PAIN 0 1 1 0 22.122.6 0 4.52 4.43
OEDEMA 0 0 2 0 0 22.6 0 0 8.86
APPLICATION SITE INDURATION 1 0 034.8 0 0 2.87 0 0
APPLICATION SITE DISCHARGE 0 1 0 0 22.1 0 0 4.52 0
FEELING ABNORMAL 0 1 0 0 22.1 0 0 4.52 0
FEELING COLD 0 1 0 0 22.1 0 0 4.52 0
APPLICATION SITE BLEEDING 0 0 1 0 0 22.6 0 0 4.43
APPLICATION SITE DESQUAMATION 0 0 1 0 0 22.6 0 0 4.43
APPLICATION SITE DISCOLOURATION 0 0 1 0 0 22.6 0 0 4.43
APPLICATION SITE WARMTH 0 0 1 0 0 22.6 0 0 4.43
INFLAMMATION 0 0 1 0 0 22.6 0 0 4.43
SECRETION DISCHARGE 0 0 1 0 0 22.6 0 0 4.43
SUDDEN DEATH 0 0 1 0 0 22.6 0 0 4.43
SWELLING 0 0 1 0 0 22.6 0 0 4.43
ULCER 0 0 1 0 0 22.6 0 0 4.43
SKIN AND SUBCUTANEOUS TISSUE DISORDERS20393934.822.122.657.47176.30172.73
PRURITUS 8252134.822.122.622.99113.01 93.01
ERYTHEMA 8141434.822.122.622.99 63.29 62.00
RASH 5 81334.822.122.614.37 36.16 57.58
HYPERHIDROSIS 2 8 434.822.122.6 5.75 36.16 17.72
SKIN IRRITATION 3 5 634.822.122.6 8.62 22.60 26.57
BLISTER 0 1 5 0 22.122.6 0 4.52 22.14
RASH PRURITIC 0 2 1 0 22.122.6 0 9.04 4.43
PRURITUS GENERALISED 0 1 1 0 22.122.6 0 4.52 4.43
URTICARIA 0 1 1 0 22.122.6 0 4.52 4.43
ALOPECIA 1 0 034.8 0 0 2.87 0 0
COLD SWEAT 1 0 034.8 0 0 2.87 0 0
DRUG ERUPTION 1 0 034.8 0 0 2.87 0 0
SKIN ULCER 1 0 034.8 0 0 2.87 0 0
ACTINIC KERATOSIS 0 1 0 0 22.1 0 0 4.52 0
RASH MACULO-PAPULAR 0 1 0 0 22.1 0 0 4.52 0
SKIN ODOUR ABNORMAL 0 1 0 0 22.1 0 0 4.52 0
DERMATITIS CONTACT 0 0 1 0 0 22.6 0 0 4.43
RASH ERYTHEMATOUS 0 0 1 0 0 22.6 0 0 4.43
SKIN EXFOLIATION 0 0 1 0 0 22.6 0 0 4.43
NERVOUS SYSTEM DISORDERS 8232234.822.122.622.99103.97 97.44
DIZZINESS 210 934.822.122.6 5.75 45.20 39.86
HEADACHE 3 5 334.822.122.6 8.62 22.60 13.29
SYNCOPE 0 2 5 0 22.122.6 0 9.04 22.14
SOMNOLENCE 2 1 334.822.122.6 5.75 4.52 13.29
TRANSIENT ISCHAEMIC ATTACK 0 1 2 0 22.122.6 0 4.52 8.86
BURNING SENSATION 0 2 0 0 22.1 0 0 9.04 0
LETHARGY 0 1 1 0 22.122.6 0 4.52 4.43
PARKINSON'S DISEASE 1 0 034.8 0 0 2.87 0 0
PSYCHOMOTOR HYPERACTIVITY 1 0 034.8 0 0 2.87 0 0
AMNESIA 0 1 0 0 22.1 0 0 4.52 0
COGNITIVE DISORDER 0 1 0 0 22.1 0 0 4.52 0
HYPERSOMNIA 0 1 0 0 22.1 0 0 4.52 0
PARAESTHESIA 0 1 0 0 22.1 0 0 4.52 0
PAROSMIA 0 1 0 0 22.1 0 0 4.52 0
PARTIAL SEIZURES WITH SECONDARY GENERALISATION 0 1 0 0 22.1 0 0 4.52 0
SYNCOPE VASOVAGAL 0 1 0 0 22.1 0 0 4.52 0
BALANCE DISORDER 0 0 1 0 0 22.6 0 0 4.43
COMPLEX PARTIAL SEIZURES 0 0 1 0 0 22.6 0 0 4.43
COORDINATION ABNORMAL 0 0 1 0 0 22.6 0 0 4.43
HEMIANOPIA HOMONYMOUS 0 0 1 0 0 22.6 0 0 4.43
PARAESTHESIA ORAL 0 0 1 0 0 22.6 0 0 4.43
STUPOR 0 0 1 0 0 22.6 0 0 4.43
GASTROINTESTINAL DISORDERS17191534.822.122.648.85 85.89 66.43
DIARRHOEA 9 3 534.822.122.625.86 13.56 22.14
VOMITING 3 6 434.822.122.6 8.62 27.12 17.72
NAUSEA 3 6 334.822.122.6 8.62 27.12 13.29
ABDOMINAL PAIN 1 1 334.822.122.6 2.87 4.52 13.29
SALIVARY HYPERSECRETION 0 4 0 0 22.1 0 0 18.08 0
DYSPEPSIA 1 0 134.8 0 22.6 2.87 0 4.43
CONSTIPATION 1 0 034.8 0 0 2.87 0 0
FLATULENCE 1 0 034.8 0 0 2.87 0 0
GASTROOESOPHAGEAL REFLUX DISEASE 1 0 034.8 0 0 2.87 0 0
GLOSSITIS 1 0 034.8 0 0 2.87 0 0
HIATUS HERNIA 1 0 034.8 0 0 2.87 0 0
ABDOMINAL DISCOMFORT 0 1 0 0 22.1 0 0 4.52 0
GASTROINTESTINAL HAEMORRHAGE 0 1 0 0 22.1 0 0 4.52 0
STOMACH DISCOMFORT 0 1 0 0 22.1 0 0 4.52 0
DYSPHAGIA 0 0 1 0 0 22.6 0 0 4.43
RECTAL HAEMORRHAGE 0 0 1 0 0 22.6 0 0 4.43
CARDIAC DISORDERS12141434.822.122.634.48 63.29 62.00
SINUS BRADYCARDIA 2 8 734.822.122.6 5.75 36.16 31.00
MYOCARDIAL INFARCTION 4 4 234.822.122.611.49 18.08 8.86
ATRIAL FIBRILLATION 1 2 234.822.122.6 2.87 9.04 8.86
SUPRAVENTRICULAR EXTRASYSTOLES 1 1 134.822.122.6 2.87 4.52 4.43
VENTRICULAR EXTRASYSTOLES 0 1 2 0 22.122.6 0 4.52 8.86
ATRIOVENTRICULAR BLOCK FIRST DEGREE 1 0 134.8 0 22.6 2.87 0 4.43
BUNDLE BRANCH BLOCK RIGHT 1 0 134.8 0 22.6 2.87 0 4.43
ATRIAL FLUTTER 0 1 1 0 22.122.6 0 4.52 4.43
PALPITATIONS 0 0 2 0 0 22.6 0 0 8.86
ATRIAL HYPERTROPHY 1 0 034.8 0 0 2.87 0 0
ATRIOVENTRICULAR BLOCK SECOND DEGREE 1 0 034.8 0 0 2.87 0 0
BRADYCARDIA 1 0 034.8 0 0 2.87 0 0
BUNDLE BRANCH BLOCK LEFT 1 0 034.8 0 0 2.87 0 0
CARDIAC FAILURE CONGESTIVE 1 0 034.8 0 0 2.87 0 0
SINUS ARRHYTHMIA 1 0 034.8 0 0 2.87 0 0
TACHYCARDIA 1 0 034.8 0 0 2.87 0 0
VENTRICULAR HYPERTROPHY 1 0 034.8 0 0 2.87 0 0
CARDIAC DISORDER 0 1 0 0 22.1 0 0 4.52 0
SUPRAVENTRICULAR TACHYCARDIA 0 0 1 0 0 22.6 0 0 4.43
WOLFF-PARKINSON-WHITE SYNDROME 0 0 1 0 0 22.6 0 0 4.43
INFECTIONS AND INFESTATIONS1613 934.822.122.645.98 58.77 39.86
NASOPHARYNGITIS 2 6 434.822.122.6 5.75 27.12 17.72
UPPER RESPIRATORY TRACT INFECTION 6 3 134.822.122.617.24 13.56 4.43
INFLUENZA 1 1 134.822.122.6 2.87 4.52 4.43
URINARY TRACT INFECTION 2 1 034.822.1 0 5.75 4.52 0
CYSTITIS 1 1 034.822.1 0 2.87 4.52 0
EAR INFECTION 2 0 034.8 0 0 5.75 0 0
BRONCHITIS 1 0 034.8 0 0 2.87 0 0
CERVICITIS 1 0 034.8 0 0 2.87 0 0
GASTROENTERITIS VIRAL 1 0 034.8 0 0 2.87 0 0
LOCALISED INFECTION 1 0 034.8 0 0 2.87 0 0
VAGINAL MYCOSIS 1 0 034.8 0 0 2.87 0 0
HORDEOLUM 0 1 0 0 22.1 0 0 4.52 0
LOWER RESPIRATORY TRACT INFECTION 0 1 0 0 22.1 0 0 4.52 0
RHINITIS 0 1 0 0 22.1 0 0 4.52 0
CELLULITIS 0 0 1 0 0 22.6 0 0 4.43
PNEUMONIA 0 0 1 0 0 22.6 0 0 4.43
VIRAL INFECTION 0 0 1 0 0 22.6 0 0 4.43
PSYCHIATRIC DISORDERS10 71134.822.122.628.73 31.64 48.72
CONFUSIONAL STATE 2 1 334.822.122.6 5.75 4.52 13.29
AGITATION 2 0 334.8 0 22.6 5.75 0 13.29
INSOMNIA 2 2 034.822.1 0 5.75 9.04 0
ANXIETY 0 0 3 0 0 22.6 0 0 13.29
DELUSION 1 1 034.822.1 0 2.87 4.52 0
IRRITABILITY 1 0 134.8 0 22.6 2.87 0 4.43
COMPLETED SUICIDE 1 0 034.8 0 0 2.87 0 0
DISORIENTATION 1 0 034.8 0 0 2.87 0 0
DELIRIUM 0 1 0 0 22.1 0 0 4.52 0
HALLUCINATION 0 1 0 0 22.1 0 0 4.52 0
HALLUCINATION, VISUAL 0 1 0 0 22.1 0 0 4.52 0
LIBIDO DECREASED 0 1 0 0 22.1 0 0 4.52 0
LISTLESS 0 1 0 0 22.1 0 0 4.52 0
NIGHTMARE 0 1 0 0 22.1 0 0 4.52 0
DEPRESSED MOOD 0 0 1 0 0 22.6 0 0 4.43
RESTLESSNESS 0 0 1 0 0 22.6 0 0 4.43
RESPIRATORY, THORACIC AND MEDIASTINAL DISORDERS 810 934.822.122.622.99 45.20 39.86
COUGH 1 5 534.822.122.6 2.87 22.60 22.14
NASAL CONGESTION 3 3 134.822.122.6 8.62 13.56 4.43
DYSPNOEA 1 1 134.822.122.6 2.87 4.52 4.43
EPISTAXIS 0 2 1 0 22.122.6 0 9.04 4.43
PHARYNGOLARYNGEAL PAIN 0 1 1 0 22.122.6 0 4.52 4.43
RHINORRHOEA 0 1 1 0 22.122.6 0 4.52 4.43
EMPHYSEMA 1 0 034.8 0 0 2.87 0 0
HAEMOPTYSIS 1 0 034.8 0 0 2.87 0 0
POSTNASAL DRIP 1 0 034.8 0 0 2.87 0 0
RALES 1 0 034.8 0 0 2.87 0 0
ALLERGIC GRANULOMATOUS ANGIITIS 0 1 0 0 22.1 0 0 4.52 0
PHARYNGEAL ERYTHEMA 0 1 0 0 22.1 0 0 4.52 0
PRODUCTIVE COUGH 0 1 0 0 22.1 0 0 4.52 0
RESPIRATORY TRACT CONGESTION 0 1 0 0 22.1 0 0 4.52 0
DYSPHONIA 0 0 1 0 0 22.6 0 0 4.43
INVESTIGATIONS10 5 734.822.122.628.73 22.60 31.00
ELECTROCARDIOGRAM ST SEGMENT DEPRESSION 4 0 134.8 0 22.611.49 0 4.43
ELECTROCARDIOGRAM T WAVE INVERSION 2 1 134.822.122.6 5.75 4.52 4.43
ELECTROCARDIOGRAM T WAVE AMPLITUDE DECREASED 1 0 134.8 0 22.6 2.87 0 4.43
BLOOD GLUCOSE INCREASED 0 1 1 0 22.122.6 0 4.52 4.43
BLOOD ALKALINE PHOSPHATASE INCREASED 1 0 034.8 0 0 2.87 0 0
BLOOD CREATINE PHOSPHOKINASE INCREASED 1 0 034.8 0 0 2.87 0 0
BLOOD URINE PRESENT 1 0 034.8 0 0 2.87 0 0
CYSTOSCOPY 1 0 034.8 0 0 2.87 0 0
HEART RATE INCREASED 1 0 034.8 0 0 2.87 0 0
HEART RATE IRREGULAR 1 0 034.8 0 0 2.87 0 0
BIOPSY 0 1 0 0 22.1 0 0 4.52 0
BIOPSY PROSTATE 0 1 0 0 22.1 0 0 4.52 0
BLOOD CHOLESTEROL INCREASED 0 1 0 0 22.1 0 0 4.52 0
BODY TEMPERATURE INCREASED 0 0 1 0 0 22.6 0 0 4.43
NASAL MUCOSA BIOPSY 0 0 1 0 0 22.6 0 0 4.43
WEIGHT DECREASED 0 0 1 0 0 22.6 0 0 4.43
MUSCULOSKELETAL AND CONNECTIVE TISSUE DISORDERS 4 7 734.822.122.611.49 31.64 31.00
BACK PAIN 1 3 134.822.122.6 2.87 13.56 4.43
ARTHRALGIA 1 1 234.822.122.6 2.87 4.52 8.86
SHOULDER PAIN 1 0 234.8 0 22.6 2.87 0 8.86
MUSCLE SPASMS 0 1 1 0 22.122.6 0 4.52 4.43
PAIN IN EXTREMITY 1 0 034.8 0 0 2.87 0 0
ARTHRITIS 0 1 0 0 22.1 0 0 4.52 0
FLANK PAIN 0 1 0 0 22.1 0 0 4.52 0
MYALGIA 0 1 0 0 22.1 0 0 4.52 0
MUSCULAR WEAKNESS 0 0 1 0 0 22.6 0 0 4.43
INJURY, POISONING AND PROCEDURAL COMPLICATIONS 4 5 534.822.122.611.49 22.60 22.14
CONTUSION 1 2 134.822.122.6 2.87 9.04 4.43
EXCORIATION 2 1 134.822.122.6 5.75 4.52 4.43
FALL 1 1 234.822.122.6 2.87 4.52 8.86
HIP FRACTURE 1 2 034.822.1 0 2.87 9.04 0
SKIN LACERATION 1 0 234.8 0 22.6 2.87 0 8.86
FACIAL BONES FRACTURE 0 1 0 0 22.1 0 0 4.52 0
JOINT DISLOCATION 0 0 1 0 0 22.6 0 0 4.43
WOUND 0 0 1 0 0 22.6 0 0 4.43
RENAL AND URINARY DISORDERS 4 3 334.822.122.611.49 13.56 13.29
MICTURITION URGENCY 1 1 134.822.122.6 2.87 4.52 4.43
DYSURIA 1 0 134.8 0 22.6 2.87 0 4.43
NEPHROLITHIASIS 1 1 034.822.1 0 2.87 4.52 0
POLLAKIURIA 1 0 034.8 0 0 2.87 0 0
CALCULUS URETHRAL 0 1 0 0 22.1 0 0 4.52 0
INCONTINENCE 0 0 1 0 0 22.6 0 0 4.43
METABOLISM AND NUTRITION DISORDERS 6 2 134.822.122.617.24 9.04 4.43
DECREASED APPETITE 1 1 034.822.1 0 2.87 4.52 0
FOOD CRAVING 1 0 134.8 0 22.6 2.87 0 4.43
INCREASED APPETITE 1 1 034.822.1 0 2.87 4.52 0
DEHYDRATION 1 0 034.8 0 0 2.87 0 0
DIABETES MELLITUS 1 0 034.8 0 0 2.87 0 0
HYPONATRAEMIA 1 0 034.8 0 0 2.87 0 0
VASCULAR DISORDERS 3 1 334.822.122.6 8.62 4.52 13.29
HYPOTENSION 2 0 134.8 0 22.6 5.75 0 4.43
HYPERTENSION 1 0 134.8 0 22.6 2.87 0 4.43
ORTHOSTATIC HYPOTENSION 1 0 034.8 0 0 2.87 0 0
WOUND HAEMORRHAGE 0 1 0 0 22.1 0 0 4.52 0
HOT FLUSH 0 0 1 0 0 22.6 0 0 4.43
EYE DISORDERS 2 1 234.822.122.6 5.75 4.52 8.86
VISION BLURRED 0 1 1 0 22.122.6 0 4.52 4.43
CONJUNCTIVITIS 1 0 034.8 0 0 2.87 0 0
EYE ALLERGY 1 0 034.8 0 0 2.87 0 0
EYE PRURITUS 1 0 034.8 0 0 2.87 0 0
EYE SWELLING 1 0 034.8 0 0 2.87 0 0
CONJUNCTIVAL HAEMORRHAGE 0 0 1 0 0 22.6 0 0 4.43
SURGICAL AND MEDICAL PROCEDURES 2 2 134.822.122.6 5.75 9.04 4.43
CATARACT OPERATION 1 0 134.8 0 22.6 2.87 0 4.43
EYE LASER SURGERY 1 0 034.8 0 0 2.87 0 0
ACROCHORDON EXCISION 0 1 0 0 22.1 0 0 4.52 0
SKIN LESION EXCISION 0 1 0 0 22.1 0 0 4.52 0
EAR AND LABYRINTH DISORDERS 1 1 234.822.122.6 2.87 4.52 8.86
VERTIGO 0 1 1 0 22.122.6 0 4.52 4.43
EAR PAIN 1 0 034.8 0 0 2.87 0 0
CERUMEN IMPACTION 0 0 1 0 0 22.6 0 0 4.43
CONGENITAL, FAMILIAL AND GENETIC DISORDERS 0 2 1 0 22.122.6 0 9.04 4.43
VENTRICULAR SEPTAL DEFECT 0 2 1 0 22.122.6 0 9.04 4.43
NEOPLASMS BENIGN, MALIGNANT AND UNSPECIFIED (INCL CYSTS AND POLYPS) 0 1 2 0 22.122.6 0 4.52 8.86
PROSTATE CANCER 0 1 0 0 22.1 0 0 4.52 0
COLON CANCER 0 0 1 0 0 22.6 0 0 4.43
MALIGNANT FIBROUS HISTIOCYTOMA 0 0 1 0 0 22.6 0 0 4.43
REPRODUCTIVE SYSTEM AND BREAST DISORDERS 2 1 034.822.1 0 5.75 4.52 0
BENIGN PROSTATIC HYPERPLASIA 1 1 034.822.1 0 2.87 4.52 0
PELVIC PAIN 1 0 034.8 0 0 2.87 0 0
HEPATOBILIARY DISORDERS 1 0 034.8 0 0 2.87 0 0
HYPERBILIRUBINAEMIA 1 0 034.8 0 0 2.87 0 0
IMMUNE SYSTEM DISORDERS 0 0 1 0 0 22.6 0 0 4.43
HYPERSENSITIVITY 0 0 1 0 0 22.6 0 0 4.43
SOCIAL CIRCUMSTANCES 0 1 0 0 22.1 0 0 4.52 0
ALCOHOL USE 0 1 0 0 22.1 0 0 4.52 0
n = number of subjects with at least one event in the category.
PY = patient-years of exposure (total duration in days / 365.25).
Rate = (n / PY) x 100. Subjects counted once per SOC and once per PT.
SOC rows sorted by descending subject frequency across all arms.
/opt/quarto/share/rmd/rmd.R 01APR2026 09:51:59
Source Code
---
title: "Exposure-Adjusted Adverse Events"
subtitle: "Incidence Rate per 100 Patient-Years"
execute:
  echo: true
  eval: true
---


```{r}
#| label: prereqs
#| include: false
library(arframe)
fr_theme(hlines = "header", font_family = "Courier New")
blank_to_na <- function(df) {
  df[] <- lapply(df, function(x) {
    if (is.character(x)) x[x == ""] <- NA_character_
    x
  })
  df
}
```

## Setup

See [Prerequisites](../install.qmd) for installation instructions.

```{r}
#| label: setup
library(arframe)
library(pharmaverseadam)
library(dplyr, warn.conflicts = FALSE)
library(tidyr)

adsl_saf <- pharmaverseadam::adsl |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRT01A != "Screen Failure")

adae_teae <- pharmaverseadam::adae |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRTEMFL == "Y")

# Total study duration per subject from ADEX (TDURD = total duration in days)
adex_tdurd <- pharmaverseadam::adex |>
  blank_to_na() |>
  filter(SAFFL == "Y", TRT01A != "Screen Failure", PARAMCD == "TDURD")

arm_levels <- c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")
```


## Data Preparation

```{r}
#| label: dplyr-code

# ── Patient-years per arm: sum subject durations / 365.25 ──
py_by_arm <- adex_tdurd |>
  filter(TRT01A %in% arm_levels) |>
  group_by(TRT01A) |>
  summarise(patient_years = sum(AVAL, na.rm = TRUE) / 365.25, .groups = "drop")

# ── Subjects with at least one TEAE per SOC/PT per arm ──
subj_soc_pt <- adae_teae |>
  distinct(USUBJID, TRT01A, AEBODSYS, AEDECOD) |>
  filter(TRT01A %in% arm_levels) |>
  count(TRT01A, AEBODSYS, AEDECOD, name = "n_subj")

# ── Subjects per SOC (deduplicated) ──
subj_soc <- adae_teae |>
  distinct(USUBJID, TRT01A, AEBODSYS) |>
  filter(TRT01A %in% arm_levels) |>
  count(TRT01A, AEBODSYS, name = "n_subj")

# ── Helper: build n / PY / Rate columns for one dataset ──
build_ea_cols <- function(count_df, by_vars, py_df) {
  count_df |>
    left_join(py_df, by = "TRT01A") |>
    mutate(
      n_col   = as.character(n_subj),
      py_col  = sprintf("%.1f", patient_years),
      rate_col = sprintf("%.2f", n_subj / patient_years * 100)
    ) |>
    select(all_of(by_vars), TRT01A, n_col, py_col, rate_col)
}

# ── SOC-level ──
soc_ea <- build_ea_cols(subj_soc, c("AEBODSYS"), py_by_arm) |>
  pivot_wider(
    names_from  = TRT01A,
    values_from = c(n_col, py_col, rate_col),
    names_glue  = "{TRT01A}__{.value}"
  ) |>
  mutate(
    soc      = AEBODSYS,
    pt       = AEBODSYS,
    row_type = "soc",
    .before  = 1
  ) |>
  select(-AEBODSYS)

# ── PT-level ──
pt_ea <- build_ea_cols(subj_soc_pt, c("AEBODSYS", "AEDECOD"), py_by_arm) |>
  pivot_wider(
    names_from  = TRT01A,
    values_from = c(n_col, py_col, rate_col),
    names_glue  = "{TRT01A}__{.value}"
  ) |>
  mutate(
    soc      = AEBODSYS,
    pt       = AEDECOD,
    row_type = "pt",
    .before  = 1
  ) |>
  select(-AEBODSYS, -AEDECOD)

# ── Sort order: SOC by descending subject count (Placebo + active combined) ──
soc_order <- adae_teae |>
  filter(TRT01A %in% arm_levels) |>
  distinct(USUBJID, AEBODSYS) |>
  count(AEBODSYS, name = "soc_n") |>
  arrange(desc(soc_n)) |>
  pull(AEBODSYS)

pt_order <- adae_teae |>
  filter(TRT01A %in% arm_levels) |>
  distinct(USUBJID, AEBODSYS, AEDECOD) |>
  count(AEBODSYS, AEDECOD, name = "pt_n") |>
  arrange(match(AEBODSYS, soc_order), desc(pt_n))

# ── Interleave SOC rows + PT rows ──
ae_ea_wide <- bind_rows(
  lapply(soc_order, function(s) {
    soc_row <- filter(soc_ea, soc == s)
    pt_rows  <- filter(pt_ea, soc == s) |>
      left_join(
        pt_order |> filter(AEBODSYS == s) |> select(pt = AEDECOD, pt_n),
        by = "pt"
      ) |>
      arrange(desc(pt_n)) |>
      select(-pt_n)
    bind_rows(soc_row, pt_rows)
  })
) |>
  mutate(across(
    where(is.character) & !c(soc, pt, row_type),
    ~ replace_na(.x, "0")
  ))
```


## arframe Pipeline

```{r}
#| label: pipeline
#| eval: false

# Build fr_col() specs in arm-grouped order: n, PY, Rate per arm
arm_col_specs <- unlist(
  lapply(arm_levels, function(a) {
    setNames(
      list(
        fr_col("n",    align = "decimal", width = 0.55),
        fr_col("PY",   align = "decimal", width = 0.65),
        fr_col("Rate", align = "decimal", width = 0.65)
      ),
      c(paste0(a, "__n_col"), paste0(a, "__py_col"), paste0(a, "__rate_col"))
    )
  }),
  recursive = FALSE
)

ae_ea_wide |>
  fr_table() |>
  fr_titles(
    "Exposure-Adjusted Adverse Events",
    "Incidence Rate per 100 Patient-Years",
    "Safety Population"
  ) |>
  fr_cols(
    soc      = fr_col(visible = FALSE),
    pt       = fr_col("System Organ Class\n  Preferred Term", width = 3.0),
    row_type = fr_col(visible = FALSE),
    !!!arm_col_specs
  ) |>
  fr_spans(
    !!!setNames(
      lapply(arm_levels, function(a) {
        c(paste0(a, "__n_col"), paste0(a, "__py_col"), paste0(a, "__rate_col"))
      }),
      arm_levels
    )
  ) |>
  fr_header(bold = TRUE, align = "center") |>
  fr_rows(
    group_by  = "soc",
    indent_by = "pt"
  ) |>
  fr_styles(
    fr_row_style(rows = fr_rows_matches("row_type", value = "soc"), bold = TRUE)
  ) |>
  fr_footnotes(
    "n = number of subjects with at least one event in the category.",
    "PY = patient-years of exposure (total duration in days / 365.25).",
    "Rate = (n / PY) x 100. Subjects counted once per SOC and once per PT.",
    "SOC rows sorted by descending subject frequency across all arms."
  )
```


## Rendered Table

```{r}
#| label: rendered-table
#| echo: false
#| ref.label: pipeline
```

Open-source TFL reference collection

 

CDISC Pilot Study (CDISCPILOT01) • pharmaverseadam datasets