TLG Catalog - Stable
  • Stable
    • Dev
  1. Tables
  2. Adverse Events
  3. AET01_AESI
  • Introduction

  • Tables
    • ADA
      • ADAT01
      • ADAT02
      • ADAT03
      • ADAT04A
      • ADAT04B
    • Adverse Events
      • AET01
      • AET01_AESI
      • AET02
      • AET02_SMQ
      • AET03
      • AET04
      • AET04_PI
      • AET05
      • AET05_ALL
      • AET06
      • AET06_SMQ
      • AET07
      • AET09
      • AET09_SMQ
      • AET10
    • Concomitant Medications
      • CMT01
      • CMT01A
      • CMT01B
      • CMT02_PT
    • Deaths
      • DTHT01
    • Demography
      • DMT01
    • Disclosures
      • DISCLOSUREST01
      • EUDRAT01
      • EUDRAT02
    • Disposition
      • DST01
      • PDT01
      • PDT02
    • ECG
      • EGT01
      • EGT02
      • EGT03
      • EGT04
      • EGT05_QTCAT
    • Efficacy
      • AOVT01
      • AOVT02
      • AOVT03
      • CFBT01
      • CMHT01
      • COXT01
      • COXT02
      • DORT01
      • LGRT02
      • MMRMT01
      • ONCT05
      • RATET01
      • RBMIT01
      • RSPT01
      • TTET01
    • Exposure
      • EXT01
    • Lab Results
      • LBT01
      • LBT02
      • LBT03
      • LBT04
      • LBT05
      • LBT06
      • LBT07
      • LBT08
      • LBT09
      • LBT10
      • LBT10_BL
      • LBT11
      • LBT11_BL
      • LBT12
      • LBT12_BL
      • LBT13
      • LBT14
      • LBT15
    • Medical History
      • MHT01
    • Pharmacokinetic
      • PKCT01
      • PKPT02
      • PKPT03
      • PKPT04
      • PKPT05
      • PKPT06
      • PKPT07
      • PKPT08
      • PKPT11
    • Risk Management Plan
      • RMPT01
      • RMPT03
      • RMPT04
      • RMPT05
      • RMPT06
    • Safety
      • ENTXX
    • Vital Signs
      • VST01
      • VST02
  • Listings
    • ADA
      • ADAL02
    • Adverse Events
      • AEL01
      • AEL01_NOLLT
      • AEL02
      • AEL02_ED
      • AEL03
      • AEL04
    • Concomitant Medications
      • CML01
      • CML02A_GL
      • CML02B_GL
    • Development Safety Update Report
      • DSUR4
    • Disposition
      • DSL01
      • DSL02
    • ECG
      • EGL01
    • Efficacy
      • ONCL01
    • Exposure
      • EXL01
    • Lab Results
      • LBL01
      • LBL01_RLS
      • LBL02A
      • LBL02A_RLS
      • LBL02B
    • Medical History
      • MHL01
    • Pharmacokinetic
      • ADAL01
      • PKCL01
      • PKCL02
      • PKPL01
      • PKPL02
      • PKPL04
    • Vital Signs
      • VSL01
  • Graphs
    • Efficacy
      • FSTG01
      • FSTG02
      • KMG01
      • MMRMG01
      • MMRMG02
    • Other
      • BRG01
      • BWG01
      • CIG01
      • IPPG01
      • LTG01
      • MNG01
    • Pharmacokinetic
      • PKCG01
      • PKCG02
      • PKCG03
      • PKPG01
      • PKPG02
      • PKPG03
      • PKPG04
      • PKPG06

  • Appendix
    • Reproducibility

  • Index

On this page

  • Output
  • teal App
  • Reproducibility
    • Timestamp
    • Session Info
    • .lock file
  • Edit this page
  • Report an issue
  1. Tables
  2. Adverse Events
  3. AET01_AESI

AET01_AESI

Safety Summary (Adverse Events of Special Interest)


Output

  • Standard Table
  • Table with
    Optional Lines
  • Table For Studies
    with Multiple Drugs
  • Table of AEs
    by SMQ
  • Data Setup
  • Preview
  • Try this using WebR
Code
aesi_vars <- c("WD", "DSM", "CONTRT", "ALL_RESOLVED", "NOT_RESOLVED", "SER", "REL")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags("USUBJID", flag_variables = aesi_vars, denom = "N_col")

result <- build_table(lyt_adae, df = adae, alt_counts_df = adsl)
result
                                                                                 A: Drug X    B: Placebo   C: Combination
                                                                                  (N=134)      (N=134)        (N=132)    
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Total number of patients with at least one AE                                   100 (74.6%)   98 (73.1%)    103 (78.0%)  
Total number of AEs                                                                 502          480            604      
Total number of patients with at least one AE by worst grade                                                             
  Grade 1                                                                        5 (3.7%)      7 (5.2%)       4 (3.0%)   
  Grade 2                                                                        5 (3.7%)      8 (6.0%)       6 (4.5%)   
  Grade 3                                                                        13 (9.7%)    13 (9.7%)      14 (10.6%)  
  Grade 4                                                                        13 (9.7%)    18 (13.4%)     15 (11.4%)  
  Grade 5 (fatal outcome)                                                       64 (47.8%)    52 (38.8%)     64 (48.5%)  
Total number of patients with study drug withdrawn due to AE                    22 (16.4%)    21 (15.7%)     28 (21.2%)  
Total number of patients with dose modified/interrupted due to AE               55 (41.0%)    62 (46.3%)     64 (48.5%)  
Total number of patients with treatment received for AE                         80 (59.7%)    80 (59.7%)     89 (67.4%)  
Total number of patients with all non-fatal AEs resolved                        17 (12.7%)    12 (9.0%)      11 (8.3%)   
Total number of patients with at least one unresolved or ongoing non-fatal AE   83 (61.9%)    86 (64.2%)     92 (69.7%)  
Total number of patients with at least one serious AE                           85 (63.4%)    80 (59.7%)     87 (65.9%)  
Total number of patients with at least one related AE                           86 (64.2%)    85 (63.4%)     92 (69.7%)  
Experimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

  • Preview
  • Try this using WebR
Code
aesi_vars <- c("WD", "DSM", "CONTRT")
aesi_resolved <- c("ALL_RESOLVED", "ALL_RESOLVED_WD", "ALL_RESOLVED_DSM", "ALL_RESOLVED_CONTRT")
aesi_not_resolved <- c("NOT_RESOLVED", "NOT_RESOLVED_WD", "NOT_RESOLVED_DSM", "NOT_RESOLVED_CONTRT")
aesi_ser <- c("SER", "SERWD", "SERDSM", "SERCONTRT")
aesi_rel <- c("REL", "RELWD", "RELDSM", "RELCONTRT", "RELSER")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = c(aesi_vars, aesi_resolved[1]), denom = "N_col"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_resolved[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_res"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_resolved[1], denom = "N_col", table_names = "fl_notres_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_resolved[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_notres"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[1], denom = "N_col", table_names = "fl_ser_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_ser"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel[1], denom = "N_col", table_names = "fl_rel_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel"
  )

result <- build_table(lyt_adae, df = adae, alt_counts_df = adsl)
result
                                                                                    A: Drug X    B: Placebo   C: Combination
                                                                                     (N=134)      (N=134)        (N=132)    
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Total number of patients with at least one AE                                      100 (74.6%)   98 (73.1%)    103 (78.0%)  
Total number of AEs                                                                    502          480            604      
Total number of patients with at least one AE by worst grade                                                                
  Grade 1                                                                           5 (3.7%)      7 (5.2%)       4 (3.0%)   
  Grade 2                                                                           5 (3.7%)      8 (6.0%)       6 (4.5%)   
  Grade 3                                                                           13 (9.7%)    13 (9.7%)      14 (10.6%)  
  Grade 4                                                                           13 (9.7%)    18 (13.4%)     15 (11.4%)  
  Grade 5 (fatal outcome)                                                          64 (47.8%)    52 (38.8%)     64 (48.5%)  
Total number of patients with study drug withdrawn due to AE                       22 (16.4%)    21 (15.7%)     28 (21.2%)  
Total number of patients with dose modified/interrupted due to AE                  55 (41.0%)    62 (46.3%)     64 (48.5%)  
Total number of patients with treatment received for AE                            80 (59.7%)    80 (59.7%)     89 (67.4%)  
Total number of patients with all non-fatal AEs resolved                           17 (12.7%)    12 (9.0%)      11 (8.3%)   
  No. of patients with study drug withdrawn due to resolved AE                          0         1 (0.7%)       2 (1.5%)   
  No. of patients with dose modified/interrupted due to resolved AE                 3 (2.2%)      4 (3.0%)       2 (1.5%)   
  No. of patients with treatment received for resolved AE                           9 (6.7%)      7 (5.2%)       7 (5.3%)   
Total number of patients with at least one unresolved or ongoing non-fatal AE      83 (61.9%)    86 (64.2%)     92 (69.7%)  
  No. of patients with study drug withdrawn due to unresolved or ongoing AE        22 (16.4%)    20 (14.9%)     26 (19.7%)  
  No. of patients with dose modified/interrupted due to unresolved or ongoing AE   52 (38.8%)    58 (43.3%)     62 (47.0%)  
  No. of patients with treatment received for unresolved or ongoing AE             71 (53.0%)    73 (54.5%)     82 (62.1%)  
Total number of patients with at least one serious AE                              85 (63.4%)    80 (59.7%)     87 (65.9%)  
  No. of patients with study drug withdrawn due to serious AE                       9 (6.7%)      4 (3.0%)      10 (7.6%)   
  No. of patients with treatment received for serious AE                           21 (15.7%)    22 (16.4%)     28 (21.2%)  
  No. of patients with dose modified/interrupted due to serious AE                 59 (44.0%)    58 (43.3%)     53 (40.2%)  
Total number of patients with at least one related AE                              86 (64.2%)    85 (63.4%)     92 (69.7%)  
  No. of patients with study drug withdrawn due to related AE                       5 (3.7%)     10 (7.5%)       7 (5.3%)   
  No. of patients with dose modified/interrupted due to related AE                 24 (17.9%)    32 (23.9%)     34 (25.8%)  
  No. of patients with treatment received for related AE                           53 (39.6%)    58 (43.3%)     60 (45.5%)  
  No. of patients with serious, related AE                                         64 (47.8%)    52 (38.8%)     64 (48.5%)  
Experimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

  • Preview
  • Try this using WebR
Code
adsl <- random.cdisc.data::cadsl
adae_mult <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae_mult <- filter(adae_mult, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae_mult <- df_explicit_na(adae_mult)

# for illustration purposes only, create AEREL1, AEREL2, AEACN1, AEACN2 from respective variables
adae_mult <- adae_mult %>%
  mutate(
    AEREL1 = AEREL,
    AEREL2 = AEREL,
    AEACN1 = AEACN,
    AEACN2 = AEACN
  )

not_resolved <- adae_mult %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae_mult <- adae_mult %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one non-fatal unresolved or ongoing AE"
    )
  )

adae_mult <- adae_mult %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD1 = with_label(
      AEACN1 == "DRUG WITHDRAWN",
      "Total number of patients with study drug 1 withdrawn due to AE"
    ),
    WD2 = with_label(
      AEACN2 == "DRUG WITHDRAWN",
      "Total number of patients with study drug 2 withdrawn due to AE"
    ),
    DSM1 = with_label(
      AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose of study drug 1 modified/interrupted due to AE"
    ),
    DSM2 = with_label(
      AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose of study drug 2 modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL1 = with_label(
      AEREL1 == "Y",
      "Total number of patients with at least one AE related to study drug 1"
    ),
    REL2 = with_label(
      AEREL2 == "Y",
      "Total number of patients with at least one AE related to study drug 2"
    ),
    ALL_RESOLVED_WD1 = with_label(
      WD1 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug 1 withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM1 = with_label(
      DSM1 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose of study drug 1 modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    ALL_RESOLVED_WD2 = with_label(
      WD2 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug 2 withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM2 = with_label(
      DSM2 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose of study drug 2 modified/interrupted due to resolved AE"
    ),
    NOT_RESOLVED_WD1 = with_label(
      WD1 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug 1 withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM1 = with_label(
      DSM1 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose of study drug 1 modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    NOT_RESOLVED_WD2 = with_label(
      WD2 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug 2 withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM2 = with_label(
      DSM2 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose of study drug 2 modified/interrupted due to unresolved or ongoing AE"
    ),
    SERWD1 = with_label(
      AESER == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to serious AE"
    ),
    SERWD2 = with_label(
      AESER == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with treatment received for serious AE"
    ),
    SERDSM1 = with_label(
      AESER == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to serious AE"
    ),
    SERDSM2 = with_label(
      AESER == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to serious AE"
    ),
    REL1WD1 = with_label(
      AEREL1 == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to AE related to study drug 1"
    ),
    REL1WD2 = with_label(
      AEREL1 == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to AE related to study drug 2"
    ),
    REL2WD1 = with_label(
      AEREL1 == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to AE related to study drug 1"
    ),
    REL2WD2 = with_label(
      AEREL1 == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to AE related to study drug 2"
    ),
    REL1DSM1 = with_label(
      AEREL1 == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 1"
    ),
    REL2DSM1 = with_label(
      AEREL2 == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 1"
    ),
    REL1DSM2 = with_label(
      AEREL1 == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 2"
    ),
    REL2DSM2 = with_label(
      AEREL2 == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 2"
    ),
    REL1CONTRT = with_label(
      AECONTRT == "Y" & AEREL1 == "Y",
      "No. of patients with treatment received for AE related to study drug 1"
    ),
    REL2CONTRT = with_label(
      AECONTRT == "Y" & AEREL2 == "Y",
      "No. of patients with treatment received for AE related to study drug 2"
    ),
    REL1SER = with_label(
      AESER == "Y" & AEREL1 == "Y",
      "No. of patients with serious AE related to study drug 1"
    ),
    REL2SER = with_label(
      AESER == "Y" & AEREL2 == "Y",
      "No. of patients with serious AE related to study drug 2"
    )
  )

adae_mult <- adae_mult %>%
  mutate(AETOXGR = forcats::fct_recode(
    AETOXGR,
    "Grade 1" = "1",
    "Grade 2" = "2",
    "Grade 3" = "3",
    "Grade 4" = "4",
    "Grade 5 (fatal outcome)" = "5"
  ))

aesi_vars <- c("WD1", "WD2", "DSM1", "DSM2", "CONTRT")
aesi_res <- c(
  "ALL_RESOLVED",
  "ALL_RESOLVED_WD1",
  "ALL_RESOLVED_WD2",
  "ALL_RESOLVED_DSM1",
  "ALL_RESOLVED_DSM2",
  "ALL_RESOLVED_CONTRT"
)
aesi_not_res <- c(
  "NOT_RESOLVED",
  "NOT_RESOLVED_WD1",
  "NOT_RESOLVED_WD2",
  "NOT_RESOLVED_DSM1",
  "NOT_RESOLVED_DSM2",
  "NOT_RESOLVED_CONTRT"
)
aesi_ser <- c("SER", "SERWD1", "SERWD2", "SERDSM1", "SERDSM2", "SERCONTRT")
aesi_rel1 <- c("REL1", "REL1WD1", "REL1WD2", "REL1DSM1", "REL1DSM2", "REL1CONTRT", "REL1SER")
aesi_rel2 <- c("REL2", "REL2WD1", "REL2WD2", "REL2DSM1", "REL2DSM2", "REL2CONTRT", "REL2SER")

lyt_adae_mult <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = c(aesi_vars, aesi_res[1]), denom = "N_col"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_res[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_res"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_res[1], denom = "N_col", table_names = "fl_notres_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_res[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_notres"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[1], denom = "N_col", table_names = "fl_ser_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_ser"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel1[1], denom = "N_col", table_names = "fl_rel1_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel1[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel1"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel2[1], denom = "N_col", table_names = "fl_rel2_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel2[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel2"
  )

result <- build_table(lyt_adae_mult, df = adae_mult, alt_counts_df = adsl)
result
                                                                                                      A: Drug X    B: Placebo   C: Combination
                                                                                                       (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Total number of patients with at least one AE                                                        100 (74.6%)   98 (73.1%)    103 (78.0%)  
Total number of AEs                                                                                      502          480            604      
Total number of patients with at least one AE by worst grade                                                                                  
  Grade 1                                                                                             5 (3.7%)      7 (5.2%)       4 (3.0%)   
  Grade 2                                                                                             5 (3.7%)      8 (6.0%)       6 (4.5%)   
  Grade 3                                                                                             13 (9.7%)    13 (9.7%)      14 (10.6%)  
  Grade 4                                                                                             13 (9.7%)    18 (13.4%)     15 (11.4%)  
  Grade 5 (fatal outcome)                                                                            64 (47.8%)    52 (38.8%)     64 (48.5%)  
Total number of patients with study drug 1 withdrawn due to AE                                       22 (16.4%)    21 (15.7%)     28 (21.2%)  
Total number of patients with study drug 2 withdrawn due to AE                                       22 (16.4%)    21 (15.7%)     28 (21.2%)  
Total number of patients with dose of study drug 1 modified/interrupted due to AE                    55 (41.0%)    62 (46.3%)     64 (48.5%)  
Total number of patients with dose of study drug 2 modified/interrupted due to AE                    55 (41.0%)    62 (46.3%)     64 (48.5%)  
Total number of patients with treatment received for AE                                              80 (59.7%)    80 (59.7%)     89 (67.4%)  
Total number of patients with all non-fatal AEs resolved                                             17 (12.7%)    12 (9.0%)      11 (8.3%)   
  No. of patients with study drug 1 withdrawn due to resolved AE                                          0         1 (0.7%)       2 (1.5%)   
  No. of patients with study drug 2 withdrawn due to resolved AE                                          0         1 (0.7%)       2 (1.5%)   
  No. of patients with dose of study drug 1 modified/interrupted due to resolved AE                   3 (2.2%)      4 (3.0%)       2 (1.5%)   
  No. of patients with dose of study drug 2 modified/interrupted due to resolved AE                   3 (2.2%)      4 (3.0%)       2 (1.5%)   
  No. of patients with treatment received for resolved AE                                             9 (6.7%)      7 (5.2%)       7 (5.3%)   
Total number of patients with at least one non-fatal unresolved or ongoing AE                        83 (61.9%)    86 (64.2%)     92 (69.7%)  
  No. of patients with study drug 1 withdrawn due to unresolved or ongoing AE                        22 (16.4%)    20 (14.9%)     26 (19.7%)  
  No. of patients with study drug 2 withdrawn due to unresolved or ongoing AE                        22 (16.4%)    20 (14.9%)     26 (19.7%)  
  No. of patients with dose of study drug 1 modified/interrupted due to unresolved or ongoing AE     52 (38.8%)    58 (43.3%)     62 (47.0%)  
  No. of patients with dose of study drug 2 modified/interrupted due to unresolved or ongoing AE     52 (38.8%)    58 (43.3%)     62 (47.0%)  
  No. of patients with treatment received for unresolved or ongoing AE                               71 (53.0%)    73 (54.5%)     82 (62.1%)  
Total number of patients with at least one serious AE                                                85 (63.4%)    80 (59.7%)     87 (65.9%)  
  No. of patients with study drug 1 withdrawn due to serious AE                                       9 (6.7%)      4 (3.0%)      10 (7.6%)   
  No. of patients with study drug 2 withdrawn due to serious AE                                       9 (6.7%)      4 (3.0%)      10 (7.6%)   
  No. of patients with dose of study drug 1 modified/interrupted due to serious AE                   21 (15.7%)    22 (16.4%)     28 (21.2%)  
  No. of patients with dose of study drug 2 modified/interrupted due to serious AE                   21 (15.7%)    22 (16.4%)     28 (21.2%)  
  No. of patients with treatment received for serious AE                                             59 (44.0%)    58 (43.3%)     53 (40.2%)  
Total number of patients with at least one AE related to study drug 1                                86 (64.2%)    85 (63.4%)     92 (69.7%)  
  No. of patients with study drug 1 withdrawn due to AE related to study drug 1                       5 (3.7%)     10 (7.5%)       7 (5.3%)   
  No. of patients with study drug 1 withdrawn due to AE related to study drug 2                       5 (3.7%)     10 (7.5%)       7 (5.3%)   
  No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 1   24 (17.9%)    32 (23.9%)     34 (25.8%)  
  No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 2   24 (17.9%)    32 (23.9%)     34 (25.8%)  
  No. of patients with treatment received for AE related to study drug 1                             53 (39.6%)    58 (43.3%)     60 (45.5%)  
  No. of patients with serious AE related to study drug 1                                            64 (47.8%)    52 (38.8%)     64 (48.5%)  
Total number of patients with at least one AE related to study drug 2                                86 (64.2%)    85 (63.4%)     92 (69.7%)  
  No. of patients with study drug 2 withdrawn due to AE related to study drug 1                       5 (3.7%)     10 (7.5%)       7 (5.3%)   
  No. of patients with study drug 2 withdrawn due to AE related to study drug 2                       5 (3.7%)     10 (7.5%)       7 (5.3%)   
  No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 1   24 (17.9%)    32 (23.9%)     34 (25.8%)  
  No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 2   24 (17.9%)    32 (23.9%)     34 (25.8%)  
  No. of patients with treatment received for AE related to study drug 2                             53 (39.6%)    58 (43.3%)     60 (45.5%)  
  No. of patients with serious AE related to study drug 2                                            64 (47.8%)    52 (38.8%)     64 (48.5%)  
Experimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

  • Preview
  • Try this using WebR
Code
adsl <- random.cdisc.data::cadsl
adae <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae <- filter(adae, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae <- df_explicit_na(adae)

stack_adae_by_smq <- function(adae, smq) {
  adae_labels <- c(var_labels(adae), "Standardized MedDRA Query")
  l_df <- lapply(smq, function(ae_grp) {
    ae_scope <- gsub("NAM", "SC", ae_grp)
    keep <- adae[[ae_grp]] != "<Missing>"
    df <- adae[keep, ]
    if (substr(ae_grp, 1, 3) == "SMQ") {
      df[["SMQ"]] <- aesi_label(as.character(df[[ae_grp]]), scope = as.character(df[[ae_scope]]))
    } else {
      df[["SMQ"]] <- df[[ae_grp]]
    }
    df
  })
  result <- do.call(rbind, l_df)
  var_labels(result) <- adae_labels
  result
}

adae_smq <- stack_adae_by_smq(adae, c("SMQ01NAM", "SMQ02NAM", "CQ01NAM"))

not_resolved <- adae_smq %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae_smq <- adae_smq %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one non-fatal unresolved or ongoing AE"
    )
  )

adae_smq <- adae_smq %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD = with_label(
      AEACN == "DRUG WITHDRAWN",
      "Total number of patients with study drug withdrawn due to AE"
    ),
    DSM = with_label(
      AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL = with_label(
      AEREL == "Y",
      "Total number of patients with at least one related AE"
    ),
    ALL_RESOLVED_WD = with_label(
      WD == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM = with_label(
      DSM == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    NOT_RESOLVED_WD = with_label(
      WD == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM = with_label(
      DSM == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    SERWD = with_label(
      AESER == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with treatment received for serious AE"
    ),
    SERDSM = with_label(
      AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to serious AE"
    ),
    RELWD = with_label(
      AEREL == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to related AE"
    ),
    RELDSM = with_label(
      AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to related AE"
    ),
    RELCONTRT = with_label(
      AECONTRT == "Y" & AEREL == "Y",
      "No. of patients with treatment received for related AE"
    ),
    RELSER = with_label(
      AESER == "Y" & AEREL == "Y",
      "No. of patients with serious, related AE"
    )
  )

adae_smq <- adae_smq %>%
  mutate(
    AETOXGR = forcats::fct_recode(AETOXGR,
      "Grade 1" = "1",
      "Grade 2" = "2",
      "Grade 3" = "3",
      "Grade 4" = "4",
      "Grade 5 (fatal outcome)" = "5"
    )
  )

split_fun <- remove_split_levels("<Missing>")
aesi_vars <- c("WD", "DSM", "CONTRT", "ALL_RESOLVED", "NOT_RESOLVED", "SER", "REL")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "SMQ",
    child_labels = "visible",
    split_fun = split_fun,
    split_label = "Standardized MedDRA Query",
    label_pos = "topleft"
  ) %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    .show_labels = "visible"
  ) %>%
  count_patients_with_flags("USUBJID", flag_variables = aesi_vars, denom = "N_col")

result <- build_table(lyt_adae, df = adae_smq, alt_counts_df = adsl)
result
                                                                                  A: Drug X    B: Placebo   C: Combination
Standardized MedDRA Query                                                          (N=134)      (N=134)        (N=132)    
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
C.1.1.1.3/B.2.2.3.1 AESI (BROAD)                                                                                          
  Total number of patients with at least one AE                                   58 (43.3%)   60 (44.8%)     66 (50.0%)  
  Total number of AEs                                                                 97          106            122      
  Total number of patients with at least one AE by worst grade                                                            
    Grade 1                                                                       22 (16.4%)   26 (19.4%)     30 (22.7%)  
    Grade 2                                                                           0            0              0       
    Grade 3                                                                           0            0              0       
    Grade 4                                                                       36 (26.9%)   34 (25.4%)     36 (27.3%)  
    Grade 5 (fatal outcome)                                                           0            0              0       
  Total number of patients with study drug withdrawn due to AE                     5 (3.7%)     6 (4.5%)       9 (6.8%)   
  Total number of patients with dose modified/interrupted due to AE               21 (15.7%)   21 (15.7%)     24 (18.2%)  
  Total number of patients with treatment received for AE                         32 (23.9%)   35 (26.1%)     44 (33.3%)  
  Total number of patients with all non-fatal AEs resolved                         7 (5.2%)     9 (6.7%)       8 (6.1%)   
  Total number of patients with at least one non-fatal unresolved or ongoing AE   51 (38.1%)   51 (38.1%)     58 (43.9%)  
  Total number of patients with at least one serious AE                           38 (28.4%)   40 (29.9%)     45 (34.1%)  
  Total number of patients with at least one related AE                           36 (26.9%)   34 (25.4%)     36 (27.3%)  
D.2.1.5.3/A.1.1.1.1 AESI                                                                                                  
  Total number of patients with at least one AE                                   62 (46.3%)   61 (45.5%)     76 (57.6%)  
  Total number of AEs                                                                106          100            139      
  Total number of patients with at least one AE by worst grade                                                            
    Grade 1                                                                       62 (46.3%)   61 (45.5%)     76 (57.6%)  
    Grade 2                                                                           0            0              0       
    Grade 3                                                                           0            0              0       
    Grade 4                                                                           0            0              0       
    Grade 5 (fatal outcome)                                                           0            0              0       
  Total number of patients with study drug withdrawn due to AE                     6 (4.5%)     8 (6.0%)       4 (3.0%)   
  Total number of patients with dose modified/interrupted due to AE               23 (17.2%)   20 (14.9%)     26 (19.7%)  
  Total number of patients with treatment received for AE                         33 (24.6%)   37 (27.6%)     33 (25.0%)  
  Total number of patients with all non-fatal AEs resolved                         4 (3.0%)     5 (3.7%)      14 (10.6%)  
  Total number of patients with at least one non-fatal unresolved or ongoing AE   58 (43.3%)   56 (41.8%)     62 (47.0%)  
  Total number of patients with at least one serious AE                               0            0              0       
  Total number of patients with at least one related AE                           37 (27.6%)   46 (34.3%)     50 (37.9%)  
Experimental use!

WebR is a tool allowing you to run R code in the web browser. Modify the code below and click run to see the results. Alternatively, copy the code and click here to open WebR in a new tab.

To illustrate, additional variables such as flags (TRUE/FALSE) for selected AEs of interest. Please consult your SAP on how to handle missing AE grades.

Code
library(tern)
library(dplyr)

adsl <- random.cdisc.data::cadsl
adae <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae <- filter(adae, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae <- df_explicit_na(adae)

not_resolved <- adae %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae <- adae %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one unresolved or ongoing non-fatal AE"
    )
  )

adae <- adae %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD = with_label(
      AEACN == "DRUG WITHDRAWN",
      "Total number of patients with study drug withdrawn due to AE"
    ),
    DSM = with_label(
      AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL = with_label(
      AEREL == "Y",
      "Total number of patients with at least one related AE"
    ),
    ALL_RESOLVED_WD = with_label(
      WD == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM = with_label(
      DSM == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    NOT_RESOLVED_WD = with_label(
      WD == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM = with_label(
      DSM == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    SERWD = with_label(
      AESER == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with dose modified/interrupted due to serious AE"
    ),
    SERDSM = with_label(
      AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with treatment received for serious AE"
    ),
    RELWD = with_label(
      AEREL == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to related AE"
    ),
    RELDSM = with_label(
      AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to related AE"
    ),
    RELCONTRT = with_label(
      AECONTRT == "Y" & AEREL == "Y",
      "No. of patients with treatment received for related AE"
    ),
    RELSER = with_label(
      AESER == "Y" & AEREL == "Y",
      "No. of patients with serious, related AE"
    )
  )

adae <- adae %>%
  mutate(
    AETOXGR = forcats::fct_recode(AETOXGR,
      "Grade 1" = "1",
      "Grade 2" = "2",
      "Grade 3" = "3",
      "Grade 4" = "4",
      "Grade 5 (fatal outcome)" = "5"
    )
  )

teal App

  • Preview
  • Try this using shinylive
Code
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  library(dplyr)

  ADSL <- random.cdisc.data::cadsl
  ADAE <- random.cdisc.data::cadae
  ADAE <- filter(ADAE, ANL01FL == "Y" & SAFFL == "Y")

  not_resolved <- ADAE %>%
    filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
    distinct(USUBJID) %>%
    mutate(NOT_RESOLVED = "Y")

  ADAE <- ADAE %>%
    left_join(not_resolved, by = c("USUBJID")) %>%
    mutate(
      ALL_RESOLVED = with_label(is.na(NOT_RESOLVED), "All non-fatal AEs resolved"),
      NOT_RESOLVED = with_label(!is.na(NOT_RESOLVED), "At least one non-fatal unresolved or ongoing AE")
    )

  ADAE <- ADAE %>%
    mutate(
      AEDECOD = as.character(AEDECOD),
      WD = with_label(AEACN == "DRUG WITHDRAWN", "AE that led to study drug withdrawal"),
      DSM = with_label(
        AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "AE that led to study drug dose modified/interrupted"
      ),
      CONTRT = with_label(AECONTRT == "Y", "AE that required treatment"),
      SER = with_label(AESER == "Y", "Serious AE"),
      REL = with_label(AEREL == "Y", "Related AE"),
      ALL_RESOLVED_WD = with_label(
        WD == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug withdrawal"
      ),
      ALL_RESOLVED_DSM = with_label(
        DSM == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug dose modified/interrupted"
      ),
      ALL_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that required treatment"
      ),
      NOT_RESOLVED_WD = with_label(
        WD == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug withdrawal"
      ),
      NOT_RESOLVED_DSM = with_label(
        DSM == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug dose modified/interrupted"
      ),
      NOT_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that required treatment"
      ),
      SERWD = with_label(
        AESER == "Y" & AEACN == "DRUG WITHDRAWN",
        "Serious AE that led to study drug withdrawal"
      ),
      SERCONTRT = with_label(
        AECONTRT == "Y" & AESER == "Y",
        "Serious AE that required treatment"
      ),
      SERDSM = with_label(
        AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Serious AE that led to study drug dose modified/interrupted"
      ),
      RELWD = with_label(
        AEREL == "Y" & AEACN == "DRUG WITHDRAWN", "Related AE that led to study drug withdrawal"
      ),
      RELDSM = with_label(
        AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Related AE that led to study drug dose modified/interrupted"
      ),
      RELCONTRT = with_label(AECONTRT == "Y" & AEREL == "Y", "Related AE that required treatment"),
      RELSER = with_label(AESER == "Y" & AEREL == "Y", "Serious related AE")
    )
})
datanames <- c("ADSL", "ADAE")
datanames(data) <- datanames
Warning: `datanames<-()` was deprecated in teal.data 0.7.0.
ℹ invalid to use `datanames()<-` or `names()<-` on an object of class
  `teal_data`. See ?names.teal_data
Code
join_keys(data) <- default_cdisc_join_keys[datanames]

aesi_vars <- c(
  "WD", "DSM", "CONTRT", "ALL_RESOLVED_WD", "ALL_RESOLVED_DSM", "ALL_RESOLVED_CONTRT",
  "NOT_RESOLVED_WD", "NOT_RESOLVED_DSM", "NOT_RESOLVED_CONTRT", "SER", "SERWD", "SERDSM",
  "SERCONTRT", "REL", "RELWD", "RELDSM", "RELCONTRT", "RELSER"
)

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_events_summary(
      label = "Adverse Events Summary",
      dataname = "ADAE",
      arm_var = choices_selected(
        choices = variable_choices("ADSL", c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      flag_var_anl = choices_selected(
        choices = variable_choices("ADAE", aesi_vars),
        selected = aesi_vars[1],
        keep_order = TRUE,
        fixed = FALSE
      ),
      add_total = TRUE
    )
  )
)

shinyApp(app$ui, app$server)

Experimental use!

shinylive allow you to modify to run shiny application entirely in the web browser. Modify the code below and click re-run the app to see the results. The performance is slighly worse and some of the features (e.g. downloading) might not work at all.

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 800
#| editorHeight: 200
#| components: [viewer, editor]
#| layout: vertical

# -- WEBR HELPERS --
options(webr_pkg_repos = c("r-universe" = "https://insightsengineering.r-universe.dev", getOption("webr_pkg_repos")))

# -- APP CODE --
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  library(dplyr)

  ADSL <- random.cdisc.data::cadsl
  ADAE <- random.cdisc.data::cadae
  ADAE <- filter(ADAE, ANL01FL == "Y" & SAFFL == "Y")

  not_resolved <- ADAE %>%
    filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
    distinct(USUBJID) %>%
    mutate(NOT_RESOLVED = "Y")

  ADAE <- ADAE %>%
    left_join(not_resolved, by = c("USUBJID")) %>%
    mutate(
      ALL_RESOLVED = with_label(is.na(NOT_RESOLVED), "All non-fatal AEs resolved"),
      NOT_RESOLVED = with_label(!is.na(NOT_RESOLVED), "At least one non-fatal unresolved or ongoing AE")
    )

  ADAE <- ADAE %>%
    mutate(
      AEDECOD = as.character(AEDECOD),
      WD = with_label(AEACN == "DRUG WITHDRAWN", "AE that led to study drug withdrawal"),
      DSM = with_label(
        AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "AE that led to study drug dose modified/interrupted"
      ),
      CONTRT = with_label(AECONTRT == "Y", "AE that required treatment"),
      SER = with_label(AESER == "Y", "Serious AE"),
      REL = with_label(AEREL == "Y", "Related AE"),
      ALL_RESOLVED_WD = with_label(
        WD == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug withdrawal"
      ),
      ALL_RESOLVED_DSM = with_label(
        DSM == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug dose modified/interrupted"
      ),
      ALL_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that required treatment"
      ),
      NOT_RESOLVED_WD = with_label(
        WD == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug withdrawal"
      ),
      NOT_RESOLVED_DSM = with_label(
        DSM == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug dose modified/interrupted"
      ),
      NOT_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that required treatment"
      ),
      SERWD = with_label(
        AESER == "Y" & AEACN == "DRUG WITHDRAWN",
        "Serious AE that led to study drug withdrawal"
      ),
      SERCONTRT = with_label(
        AECONTRT == "Y" & AESER == "Y",
        "Serious AE that required treatment"
      ),
      SERDSM = with_label(
        AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Serious AE that led to study drug dose modified/interrupted"
      ),
      RELWD = with_label(
        AEREL == "Y" & AEACN == "DRUG WITHDRAWN", "Related AE that led to study drug withdrawal"
      ),
      RELDSM = with_label(
        AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Related AE that led to study drug dose modified/interrupted"
      ),
      RELCONTRT = with_label(AECONTRT == "Y" & AEREL == "Y", "Related AE that required treatment"),
      RELSER = with_label(AESER == "Y" & AEREL == "Y", "Serious related AE")
    )
})
datanames <- c("ADSL", "ADAE")
datanames(data) <- datanames
join_keys(data) <- default_cdisc_join_keys[datanames]

aesi_vars <- c(
  "WD", "DSM", "CONTRT", "ALL_RESOLVED_WD", "ALL_RESOLVED_DSM", "ALL_RESOLVED_CONTRT",
  "NOT_RESOLVED_WD", "NOT_RESOLVED_DSM", "NOT_RESOLVED_CONTRT", "SER", "SERWD", "SERDSM",
  "SERCONTRT", "REL", "RELWD", "RELDSM", "RELCONTRT", "RELSER"
)

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_events_summary(
      label = "Adverse Events Summary",
      dataname = "ADAE",
      arm_var = choices_selected(
        choices = variable_choices("ADSL", c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      flag_var_anl = choices_selected(
        choices = variable_choices("ADAE", aesi_vars),
        selected = aesi_vars[1],
        keep_order = TRUE,
        fixed = FALSE
      ),
      add_total = TRUE
    )
  )
)

shinyApp(app$ui, app$server)

Reproducibility

Timestamp

[1] "2025-07-05 17:55:46 UTC"

Session Info

─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.5.0 (2025-04-11)
 os       Ubuntu 24.04.2 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Etc/UTC
 date     2025-07-05
 pandoc   3.7.0.2 @ /usr/bin/ (via rmarkdown)
 quarto   1.7.32 @ /usr/local/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package               * version  date (UTC) lib source
 backports               1.5.0    2024-05-23 [1] RSPM
 brio                    1.1.5    2024-04-24 [1] RSPM
 broom                   1.0.8    2025-03-28 [1] RSPM
 bslib                   0.9.0    2025-01-30 [1] RSPM
 cachem                  1.1.0    2024-05-16 [1] RSPM
 callr                   3.7.6    2024-03-25 [1] RSPM
 checkmate               2.3.2    2024-07-29 [1] RSPM
 chromote                0.5.1    2025-04-24 [1] RSPM
 cli                     3.6.5    2025-04-23 [1] RSPM
 coda                    0.19-4.1 2024-01-31 [1] CRAN (R 4.5.0)
 codetools               0.2-20   2024-03-31 [2] CRAN (R 4.5.0)
 curl                    6.4.0    2025-06-22 [1] RSPM
 dichromat               2.0-0.1  2022-05-02 [1] CRAN (R 4.5.0)
 digest                  0.6.37   2024-08-19 [1] RSPM
 dplyr                 * 1.1.4    2023-11-17 [1] RSPM
 emmeans                 1.11.1   2025-05-04 [1] RSPM
 estimability            1.5.1    2024-05-12 [1] RSPM
 evaluate                1.0.4    2025-06-18 [1] RSPM
 farver                  2.1.2    2024-05-13 [1] RSPM
 fastmap                 1.2.0    2024-05-15 [1] RSPM
 fontawesome             0.5.3    2024-11-16 [1] RSPM
 forcats                 1.0.0    2023-01-29 [1] RSPM
 formatR                 1.14     2023-01-17 [1] CRAN (R 4.5.0)
 formatters            * 0.5.11   2025-04-09 [1] RSPM
 geepack                 1.3.12   2024-09-23 [1] RSPM
 generics                0.1.4    2025-05-09 [1] RSPM
 ggplot2                 3.5.2    2025-04-09 [1] RSPM
 glue                    1.8.0    2024-09-30 [1] RSPM
 gtable                  0.3.6    2024-10-25 [1] RSPM
 htmltools               0.5.8.1  2024-04-04 [1] RSPM
 htmlwidgets             1.6.4    2023-12-06 [1] RSPM
 httpuv                  1.6.16   2025-04-16 [1] RSPM
 jquerylib               0.1.4    2021-04-26 [1] RSPM
 jsonlite                2.0.0    2025-03-27 [1] RSPM
 knitr                   1.50     2025-03-16 [1] RSPM
 later                   1.4.2    2025-04-08 [1] RSPM
 lattice                 0.22-7   2025-04-02 [2] CRAN (R 4.5.0)
 lifecycle               1.0.4    2023-11-07 [1] RSPM
 logger                  0.4.0    2024-10-22 [1] RSPM
 magrittr              * 2.0.3    2022-03-30 [1] RSPM
 MASS                    7.3-65   2025-02-28 [2] CRAN (R 4.5.0)
 Matrix                  1.7-3    2025-03-11 [1] CRAN (R 4.5.0)
 memoise                 2.0.1    2021-11-26 [1] RSPM
 mime                    0.13     2025-03-17 [1] RSPM
 multcomp                1.4-28   2025-01-29 [1] RSPM
 mvtnorm                 1.3-3    2025-01-10 [1] RSPM
 nestcolor               0.1.3    2025-01-21 [1] RSPM
 nlme                    3.1-168  2025-03-31 [2] CRAN (R 4.5.0)
 pillar                  1.11.0   2025-07-04 [1] RSPM
 pkgcache                2.2.4    2025-05-26 [1] RSPM
 pkgconfig               2.0.3    2019-09-22 [1] RSPM
 processx                3.8.6    2025-02-21 [1] RSPM
 promises                1.3.3    2025-05-29 [1] RSPM
 ps                      1.9.1    2025-04-12 [1] RSPM
 purrr                   1.0.4    2025-02-05 [1] RSPM
 R6                      2.6.1    2025-02-15 [1] RSPM
 random.cdisc.data       0.3.16   2024-10-10 [1] RSPM
 rbibutils               2.3      2024-10-04 [1] RSPM
 RColorBrewer            1.1-3    2022-04-03 [1] RSPM
 Rcpp                    1.1.0    2025-07-02 [1] RSPM
 Rdpack                  2.6.4    2025-04-09 [1] RSPM
 rlang                   1.1.6    2025-04-11 [1] RSPM
 rmarkdown               2.29     2024-11-04 [1] RSPM
 rtables               * 0.6.13   2025-06-19 [1] RSPM
 sandwich                3.1-1    2024-09-15 [1] RSPM
 sass                    0.4.10   2025-04-11 [1] RSPM
 scales                  1.4.0    2025-04-24 [1] RSPM
 sessioninfo             1.2.3    2025-02-05 [1] any (@1.2.3)
 shiny                 * 1.11.1   2025-07-03 [1] RSPM
 shinycssloaders         1.1.0    2024-07-30 [1] RSPM
 shinyjs                 2.1.0    2021-12-23 [1] RSPM
 shinyvalidate           0.1.3    2023-10-04 [1] RSPM
 shinyWidgets            0.9.0    2025-02-21 [1] RSPM
 stringi                 1.8.7    2025-03-27 [1] RSPM
 stringr                 1.5.1    2023-11-14 [1] RSPM
 survival                3.8-3    2024-12-17 [2] CRAN (R 4.5.0)
 teal                  * 0.16.0   2025-02-23 [1] RSPM
 teal.code             * 0.6.1    2025-02-14 [1] RSPM
 teal.data             * 0.7.0    2025-01-28 [1] RSPM
 teal.logger             0.3.2    2025-02-14 [1] RSPM
 teal.modules.clinical * 0.10.0   2025-02-28 [1] RSPM
 teal.reporter           0.4.0    2025-01-24 [1] RSPM
 teal.slice            * 0.6.0    2025-02-03 [1] RSPM
 teal.transform        * 0.6.0    2025-02-12 [1] RSPM
 teal.widgets            0.4.3    2025-01-31 [1] RSPM
 tern                  * 0.9.9    2025-06-20 [1] RSPM
 tern.gee                0.1.5    2024-08-23 [1] RSPM
 testthat                3.2.3    2025-01-13 [1] RSPM
 TH.data                 1.1-3    2025-01-17 [1] RSPM
 tibble                  3.3.0    2025-06-08 [1] RSPM
 tidyr                   1.3.1    2024-01-24 [1] RSPM
 tidyselect              1.2.1    2024-03-11 [1] RSPM
 vctrs                   0.6.5    2023-12-01 [1] RSPM
 webshot                 0.5.5    2023-06-26 [1] CRAN (R 4.5.0)
 webshot2                0.1.2    2025-04-23 [1] RSPM
 websocket               1.4.4    2025-04-10 [1] RSPM
 withr                   3.0.2    2024-10-28 [1] RSPM
 xfun                    0.52     2025-04-02 [1] RSPM
 xtable                  1.8-4    2019-04-21 [1] RSPM
 yaml                    2.3.10   2024-07-26 [1] RSPM
 zoo                     1.8-14   2025-04-10 [1] RSPM

 [1] /usr/local/lib/R/site-library
 [2] /usr/local/lib/R/library
 [3] /github/home/R/x86_64-pc-linux-gnu-library/4.5
 * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────

.lock file

Download the .lock file and use renv::restore() on it to recreate environment used to generate this website.

Download

AET01
AET02
Source Code
---
title: AET01_AESI
subtitle: Safety Summary (Adverse Events of Special Interest)
---

------------------------------------------------------------------------

{{< include ../../_utils/envir_hook.qmd >}}

```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
library(tern)
library(dplyr)

adsl <- random.cdisc.data::cadsl
adae <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae <- filter(adae, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae <- df_explicit_na(adae)

not_resolved <- adae %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae <- adae %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one unresolved or ongoing non-fatal AE"
    )
  )

adae <- adae %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD = with_label(
      AEACN == "DRUG WITHDRAWN",
      "Total number of patients with study drug withdrawn due to AE"
    ),
    DSM = with_label(
      AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL = with_label(
      AEREL == "Y",
      "Total number of patients with at least one related AE"
    ),
    ALL_RESOLVED_WD = with_label(
      WD == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM = with_label(
      DSM == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    NOT_RESOLVED_WD = with_label(
      WD == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM = with_label(
      DSM == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    SERWD = with_label(
      AESER == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with dose modified/interrupted due to serious AE"
    ),
    SERDSM = with_label(
      AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with treatment received for serious AE"
    ),
    RELWD = with_label(
      AEREL == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to related AE"
    ),
    RELDSM = with_label(
      AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to related AE"
    ),
    RELCONTRT = with_label(
      AECONTRT == "Y" & AEREL == "Y",
      "No. of patients with treatment received for related AE"
    ),
    RELSER = with_label(
      AESER == "Y" & AEREL == "Y",
      "No. of patients with serious, related AE"
    )
  )

adae <- adae %>%
  mutate(
    AETOXGR = forcats::fct_recode(AETOXGR,
      "Grade 1" = "1",
      "Grade 2" = "2",
      "Grade 3" = "3",
      "Grade 4" = "4",
      "Grade 5 (fatal outcome)" = "5"
    )
  )
```

```{r include = FALSE}
webr_code_labels <- c("setup")
```

{{< include ../../_utils/webr_no_include.qmd >}}

## Output

::::::: panel-tabset
## Standard Table

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview

```{r variant1, test = list(result_v1 = "result")}
aesi_vars <- c("WD", "DSM", "CONTRT", "ALL_RESOLVED", "NOT_RESOLVED", "SER", "REL")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags("USUBJID", flag_variables = aesi_vars, denom = "N_col")

result <- build_table(lyt_adae, df = adae, alt_counts_df = adsl)
result
```

```{r include = FALSE}
webr_code_labels <- c("variant1")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table with <br/> Optional Lines

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview

```{r variant2, test = list(result_v2 = "result")}
aesi_vars <- c("WD", "DSM", "CONTRT")
aesi_resolved <- c("ALL_RESOLVED", "ALL_RESOLVED_WD", "ALL_RESOLVED_DSM", "ALL_RESOLVED_CONTRT")
aesi_not_resolved <- c("NOT_RESOLVED", "NOT_RESOLVED_WD", "NOT_RESOLVED_DSM", "NOT_RESOLVED_CONTRT")
aesi_ser <- c("SER", "SERWD", "SERDSM", "SERCONTRT")
aesi_rel <- c("REL", "RELWD", "RELDSM", "RELCONTRT", "RELSER")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = c(aesi_vars, aesi_resolved[1]), denom = "N_col"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_resolved[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_res"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_resolved[1], denom = "N_col", table_names = "fl_notres_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_resolved[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_notres"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[1], denom = "N_col", table_names = "fl_ser_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_ser"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel[1], denom = "N_col", table_names = "fl_rel_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel"
  )

result <- build_table(lyt_adae, df = adae, alt_counts_df = adsl)
result
```

```{r include = FALSE}
webr_code_labels <- c("variant2")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table For Studies <br/> with Multiple Drugs

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview

```{r variant3, test = list(result_v3 = "result")}
adsl <- random.cdisc.data::cadsl
adae_mult <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae_mult <- filter(adae_mult, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae_mult <- df_explicit_na(adae_mult)

# for illustration purposes only, create AEREL1, AEREL2, AEACN1, AEACN2 from respective variables
adae_mult <- adae_mult %>%
  mutate(
    AEREL1 = AEREL,
    AEREL2 = AEREL,
    AEACN1 = AEACN,
    AEACN2 = AEACN
  )

not_resolved <- adae_mult %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae_mult <- adae_mult %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one non-fatal unresolved or ongoing AE"
    )
  )

adae_mult <- adae_mult %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD1 = with_label(
      AEACN1 == "DRUG WITHDRAWN",
      "Total number of patients with study drug 1 withdrawn due to AE"
    ),
    WD2 = with_label(
      AEACN2 == "DRUG WITHDRAWN",
      "Total number of patients with study drug 2 withdrawn due to AE"
    ),
    DSM1 = with_label(
      AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose of study drug 1 modified/interrupted due to AE"
    ),
    DSM2 = with_label(
      AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose of study drug 2 modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL1 = with_label(
      AEREL1 == "Y",
      "Total number of patients with at least one AE related to study drug 1"
    ),
    REL2 = with_label(
      AEREL2 == "Y",
      "Total number of patients with at least one AE related to study drug 2"
    ),
    ALL_RESOLVED_WD1 = with_label(
      WD1 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug 1 withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM1 = with_label(
      DSM1 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose of study drug 1 modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    ALL_RESOLVED_WD2 = with_label(
      WD2 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug 2 withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM2 = with_label(
      DSM2 == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose of study drug 2 modified/interrupted due to resolved AE"
    ),
    NOT_RESOLVED_WD1 = with_label(
      WD1 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug 1 withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM1 = with_label(
      DSM1 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose of study drug 1 modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    NOT_RESOLVED_WD2 = with_label(
      WD2 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug 2 withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM2 = with_label(
      DSM2 == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose of study drug 2 modified/interrupted due to unresolved or ongoing AE"
    ),
    SERWD1 = with_label(
      AESER == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to serious AE"
    ),
    SERWD2 = with_label(
      AESER == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with treatment received for serious AE"
    ),
    SERDSM1 = with_label(
      AESER == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to serious AE"
    ),
    SERDSM2 = with_label(
      AESER == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to serious AE"
    ),
    REL1WD1 = with_label(
      AEREL1 == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to AE related to study drug 1"
    ),
    REL1WD2 = with_label(
      AEREL1 == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 1 withdrawn due to AE related to study drug 2"
    ),
    REL2WD1 = with_label(
      AEREL1 == "Y" & AEACN1 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to AE related to study drug 1"
    ),
    REL2WD2 = with_label(
      AEREL1 == "Y" & AEACN2 == "DRUG WITHDRAWN",
      "No. of patients with study drug 2 withdrawn due to AE related to study drug 2"
    ),
    REL1DSM1 = with_label(
      AEREL1 == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 1"
    ),
    REL2DSM1 = with_label(
      AEREL2 == "Y" & AEACN1 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 1"
    ),
    REL1DSM2 = with_label(
      AEREL1 == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 1 modified/interrupted due to AE related to study drug 2"
    ),
    REL2DSM2 = with_label(
      AEREL2 == "Y" & AEACN2 %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose of study drug 2 modified/interrupted due to AE related to study drug 2"
    ),
    REL1CONTRT = with_label(
      AECONTRT == "Y" & AEREL1 == "Y",
      "No. of patients with treatment received for AE related to study drug 1"
    ),
    REL2CONTRT = with_label(
      AECONTRT == "Y" & AEREL2 == "Y",
      "No. of patients with treatment received for AE related to study drug 2"
    ),
    REL1SER = with_label(
      AESER == "Y" & AEREL1 == "Y",
      "No. of patients with serious AE related to study drug 1"
    ),
    REL2SER = with_label(
      AESER == "Y" & AEREL2 == "Y",
      "No. of patients with serious AE related to study drug 2"
    )
  )

adae_mult <- adae_mult %>%
  mutate(AETOXGR = forcats::fct_recode(
    AETOXGR,
    "Grade 1" = "1",
    "Grade 2" = "2",
    "Grade 3" = "3",
    "Grade 4" = "4",
    "Grade 5 (fatal outcome)" = "5"
  ))

aesi_vars <- c("WD1", "WD2", "DSM1", "DSM2", "CONTRT")
aesi_res <- c(
  "ALL_RESOLVED",
  "ALL_RESOLVED_WD1",
  "ALL_RESOLVED_WD2",
  "ALL_RESOLVED_DSM1",
  "ALL_RESOLVED_DSM2",
  "ALL_RESOLVED_CONTRT"
)
aesi_not_res <- c(
  "NOT_RESOLVED",
  "NOT_RESOLVED_WD1",
  "NOT_RESOLVED_WD2",
  "NOT_RESOLVED_DSM1",
  "NOT_RESOLVED_DSM2",
  "NOT_RESOLVED_CONTRT"
)
aesi_ser <- c("SER", "SERWD1", "SERWD2", "SERDSM1", "SERDSM2", "SERCONTRT")
aesi_rel1 <- c("REL1", "REL1WD1", "REL1WD2", "REL1DSM1", "REL1DSM2", "REL1CONTRT", "REL1SER")
aesi_rel2 <- c("REL2", "REL2WD1", "REL2WD2", "REL2DSM1", "REL2DSM2", "REL2CONTRT", "REL2SER")

lyt_adae_mult <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    show_labels = "visible"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = c(aesi_vars, aesi_res[1]), denom = "N_col"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_res[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_res"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_res[1], denom = "N_col", table_names = "fl_notres_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_not_res[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_notres"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[1], denom = "N_col", table_names = "fl_ser_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_ser[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_ser"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel1[1], denom = "N_col", table_names = "fl_rel1_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel1[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel1"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel2[1], denom = "N_col", table_names = "fl_rel2_main"
  ) %>%
  count_patients_with_flags(
    "USUBJID",
    flag_variables = aesi_rel2[-1], denom = "N_col", .indent_mods = 1L, table_names = "fl_rel2"
  )

result <- build_table(lyt_adae_mult, df = adae_mult, alt_counts_df = adsl)
result
```

```{r include = FALSE}
webr_code_labels <- c("variant3")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Table of AEs <br/> by SMQ

::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview

```{r variant4, test = list(result_v4 = "result")}
adsl <- random.cdisc.data::cadsl
adae <- random.cdisc.data::cadae

adsl <- filter(adsl, SAFFL == "Y")
adae <- filter(adae, ANL01FL == "Y" & SAFFL == "Y")

adsl <- df_explicit_na(adsl)
adae <- df_explicit_na(adae)

stack_adae_by_smq <- function(adae, smq) {
  adae_labels <- c(var_labels(adae), "Standardized MedDRA Query")
  l_df <- lapply(smq, function(ae_grp) {
    ae_scope <- gsub("NAM", "SC", ae_grp)
    keep <- adae[[ae_grp]] != "<Missing>"
    df <- adae[keep, ]
    if (substr(ae_grp, 1, 3) == "SMQ") {
      df[["SMQ"]] <- aesi_label(as.character(df[[ae_grp]]), scope = as.character(df[[ae_scope]]))
    } else {
      df[["SMQ"]] <- df[[ae_grp]]
    }
    df
  })
  result <- do.call(rbind, l_df)
  var_labels(result) <- adae_labels
  result
}

adae_smq <- stack_adae_by_smq(adae, c("SMQ01NAM", "SMQ02NAM", "CQ01NAM"))

not_resolved <- adae_smq %>%
  filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
  distinct(USUBJID) %>%
  mutate(NOT_RESOLVED = "Y")

adae_smq <- adae_smq %>%
  left_join(not_resolved, by = c("USUBJID")) %>%
  mutate(
    ALL_RESOLVED = with_label(
      is.na(NOT_RESOLVED),
      "Total number of patients with all non-fatal AEs resolved"
    ),
    NOT_RESOLVED = with_label(
      !is.na(NOT_RESOLVED),
      "Total number of patients with at least one non-fatal unresolved or ongoing AE"
    )
  )

adae_smq <- adae_smq %>%
  mutate(
    AEDECOD = as.character(AEDECOD),
    WD = with_label(
      AEACN == "DRUG WITHDRAWN",
      "Total number of patients with study drug withdrawn due to AE"
    ),
    DSM = with_label(
      AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "Total number of patients with dose modified/interrupted due to AE"
    ),
    CONTRT = with_label(
      AECONTRT == "Y",
      "Total number of patients with treatment received for AE"
    ),
    SER = with_label(
      AESER == "Y",
      "Total number of patients with at least one serious AE"
    ),
    REL = with_label(
      AEREL == "Y",
      "Total number of patients with at least one related AE"
    ),
    ALL_RESOLVED_WD = with_label(
      WD == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to resolved AE"
    ),
    ALL_RESOLVED_DSM = with_label(
      DSM == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to resolved AE"
    ),
    ALL_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & ALL_RESOLVED == TRUE,
      "No. of patients with treatment received for resolved AE"
    ),
    NOT_RESOLVED_WD = with_label(
      WD == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with study drug withdrawn due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_DSM = with_label(
      DSM == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with dose modified/interrupted due to unresolved or ongoing AE"
    ),
    NOT_RESOLVED_CONTRT = with_label(
      CONTRT == TRUE & NOT_RESOLVED == TRUE,
      "No. of patients with treatment received for unresolved or ongoing AE"
    ),
    SERWD = with_label(
      AESER == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to serious AE"
    ),
    SERCONTRT = with_label(
      AECONTRT == "Y" & AESER == "Y",
      "No. of patients with treatment received for serious AE"
    ),
    SERDSM = with_label(
      AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to serious AE"
    ),
    RELWD = with_label(
      AEREL == "Y" & AEACN == "DRUG WITHDRAWN",
      "No. of patients with study drug withdrawn due to related AE"
    ),
    RELDSM = with_label(
      AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
      "No. of patients with dose modified/interrupted due to related AE"
    ),
    RELCONTRT = with_label(
      AECONTRT == "Y" & AEREL == "Y",
      "No. of patients with treatment received for related AE"
    ),
    RELSER = with_label(
      AESER == "Y" & AEREL == "Y",
      "No. of patients with serious, related AE"
    )
  )

adae_smq <- adae_smq %>%
  mutate(
    AETOXGR = forcats::fct_recode(AETOXGR,
      "Grade 1" = "1",
      "Grade 2" = "2",
      "Grade 3" = "3",
      "Grade 4" = "4",
      "Grade 5 (fatal outcome)" = "5"
    )
  )

split_fun <- remove_split_levels("<Missing>")
aesi_vars <- c("WD", "DSM", "CONTRT", "ALL_RESOLVED", "NOT_RESOLVED", "SER", "REL")

lyt_adae <- basic_table(show_colcounts = TRUE) %>%
  split_cols_by("ACTARM") %>%
  split_rows_by(
    "SMQ",
    child_labels = "visible",
    split_fun = split_fun,
    split_label = "Standardized MedDRA Query",
    label_pos = "topleft"
  ) %>%
  count_patients_with_event(
    vars = "USUBJID",
    filters = c("ANL01FL" = "Y"),
    denom = "N_col",
    .labels = c(count_fraction = "Total number of patients with at least one AE")
  ) %>%
  count_values(
    "ANL01FL",
    values = "Y",
    .stats = "count",
    .labels = c(count = "Total number of AEs"),
    table_names = "total_aes"
  ) %>%
  count_occurrences_by_grade(
    var = "AETOXGR",
    var_labels = "Total number of patients with at least one AE by worst grade",
    .show_labels = "visible"
  ) %>%
  count_patients_with_flags("USUBJID", flag_variables = aesi_vars, denom = "N_col")

result <- build_table(lyt_adae, df = adae_smq, alt_counts_df = adsl)
result
```

```{r include = FALSE}
webr_code_labels <- c("variant4")
```

{{< include ../../_utils/webr.qmd >}}
:::

## Data Setup

To illustrate, additional variables such as flags (TRUE/FALSE) for selected AEs of interest. Please consult your SAP on how to handle missing AE grades.

```{r setup}
#| code-fold: show
```
:::::::

{{< include ../../_utils/save_results.qmd >}}

## `teal` App

::: {.panel-tabset .nav-justified}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview

```{r teal, opts.label = c("skip_if_testing", "app")}
library(teal.modules.clinical)

## Data reproducible code
data <- teal_data()
data <- within(data, {
  library(dplyr)

  ADSL <- random.cdisc.data::cadsl
  ADAE <- random.cdisc.data::cadae
  ADAE <- filter(ADAE, ANL01FL == "Y" & SAFFL == "Y")

  not_resolved <- ADAE %>%
    filter(!(AEOUT %in% c("RECOVERED/RESOLVED", "FATAL", "RECOVERED/RESOLVED WITH SEQUELAE"))) %>%
    distinct(USUBJID) %>%
    mutate(NOT_RESOLVED = "Y")

  ADAE <- ADAE %>%
    left_join(not_resolved, by = c("USUBJID")) %>%
    mutate(
      ALL_RESOLVED = with_label(is.na(NOT_RESOLVED), "All non-fatal AEs resolved"),
      NOT_RESOLVED = with_label(!is.na(NOT_RESOLVED), "At least one non-fatal unresolved or ongoing AE")
    )

  ADAE <- ADAE %>%
    mutate(
      AEDECOD = as.character(AEDECOD),
      WD = with_label(AEACN == "DRUG WITHDRAWN", "AE that led to study drug withdrawal"),
      DSM = with_label(
        AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "AE that led to study drug dose modified/interrupted"
      ),
      CONTRT = with_label(AECONTRT == "Y", "AE that required treatment"),
      SER = with_label(AESER == "Y", "Serious AE"),
      REL = with_label(AEREL == "Y", "Related AE"),
      ALL_RESOLVED_WD = with_label(
        WD == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug withdrawal"
      ),
      ALL_RESOLVED_DSM = with_label(
        DSM == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that led to study drug dose modified/interrupted"
      ),
      ALL_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & ALL_RESOLVED == TRUE,
        "Resolved AE that required treatment"
      ),
      NOT_RESOLVED_WD = with_label(
        WD == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug withdrawal"
      ),
      NOT_RESOLVED_DSM = with_label(
        DSM == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that led to study drug dose modified/interrupted"
      ),
      NOT_RESOLVED_CONTRT = with_label(
        CONTRT == TRUE & NOT_RESOLVED == TRUE,
        "Unresolved AE that required treatment"
      ),
      SERWD = with_label(
        AESER == "Y" & AEACN == "DRUG WITHDRAWN",
        "Serious AE that led to study drug withdrawal"
      ),
      SERCONTRT = with_label(
        AECONTRT == "Y" & AESER == "Y",
        "Serious AE that required treatment"
      ),
      SERDSM = with_label(
        AESER == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Serious AE that led to study drug dose modified/interrupted"
      ),
      RELWD = with_label(
        AEREL == "Y" & AEACN == "DRUG WITHDRAWN", "Related AE that led to study drug withdrawal"
      ),
      RELDSM = with_label(
        AEREL == "Y" & AEACN %in% c("DRUG INTERRUPTED", "DOSE INCREASED", "DOSE REDUCED"),
        "Related AE that led to study drug dose modified/interrupted"
      ),
      RELCONTRT = with_label(AECONTRT == "Y" & AEREL == "Y", "Related AE that required treatment"),
      RELSER = with_label(AESER == "Y" & AEREL == "Y", "Serious related AE")
    )
})
datanames <- c("ADSL", "ADAE")
datanames(data) <- datanames
join_keys(data) <- default_cdisc_join_keys[datanames]

aesi_vars <- c(
  "WD", "DSM", "CONTRT", "ALL_RESOLVED_WD", "ALL_RESOLVED_DSM", "ALL_RESOLVED_CONTRT",
  "NOT_RESOLVED_WD", "NOT_RESOLVED_DSM", "NOT_RESOLVED_CONTRT", "SER", "SERWD", "SERDSM",
  "SERCONTRT", "REL", "RELWD", "RELDSM", "RELCONTRT", "RELSER"
)

## Setup App
app <- init(
  data = data,
  modules = modules(
    tm_t_events_summary(
      label = "Adverse Events Summary",
      dataname = "ADAE",
      arm_var = choices_selected(
        choices = variable_choices("ADSL", c("ARM", "ARMCD")),
        selected = "ARM"
      ),
      flag_var_anl = choices_selected(
        choices = variable_choices("ADAE", aesi_vars),
        selected = aesi_vars[1],
        keep_order = TRUE,
        fixed = FALSE
      ),
      add_total = TRUE
    )
  )
)

shinyApp(app$ui, app$server)
```

{{< include ../../_utils/shinylive.qmd >}}
:::

{{< include ../../repro.qmd >}}

Made with ❤️ by the NEST Team

  • Edit this page
  • Report an issue
Cookie Preferences