# Define the split functionsplit_fun <- drop_split_levelslyt <-basic_table(show_colcounts =TRUE) %>%split_cols_by(var ="ARM") %>%add_overall_col(label ="All Patients") %>%analyze_num_patients(vars ="USUBJID",.stats =c("unique", "nonunique"),.labels =c(unique ="Total number of patients with at least one adverse event related to study drug",nonunique ="Overall total number of events related to study drug" ) ) %>%split_rows_by("AEBODSYS",child_labels ="visible",nested =FALSE,split_fun = split_fun,label_pos ="topleft",split_label =obj_label(adae_f$AEBODSYS) ) %>%summarize_num_patients(var ="USUBJID",.stats =c("unique", "nonunique"),.labels =c(unique ="Total number of patients with at least one adverse event related to study drug",nonunique ="Total number of events related to study drug" ) ) %>%count_occurrences(vars ="AEDECOD",.indent_mods =-1L ) %>%append_varlabels(adae_f, "AEDECOD", indent =1L)tbl1 <-build_table(lyt = lyt,df = adae_f,alt_counts_df = adsl) %>%prune_table()result <- tbl1 %>%prune_table() %>%sort_at_path(path =c("AEBODSYS"),scorefun = cont_n_allcols ) %>%sort_at_path(path =c("AEBODSYS", "*", "AEDECOD"),scorefun = score_occurrences )result
Body System or Organ Class A: Drug X B: Placebo C: Combination All Patients
Dictionary-Derived Term (N=134) (N=134) (N=132) (N=400)
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Total number of patients with at least one adverse event related to study drug 105 (78.4%) 108 (80.6%) 109 (82.6%) 322 (80.5%)
Overall total number of events related to study drug 282 299 336 917
cl D.2
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 58 (43.3%) 57 (43.2%) 162 (40.5%)
Total number of events related to study drug 62 72 74 208
dcd D.2.1.5.3 47 (35.1%) 58 (43.3%) 57 (43.2%) 162 (40.5%)
cl D.1
Total number of patients with at least one adverse event related to study drug 50 (37.3%) 42 (31.3%) 51 (38.6%) 143 (35.8%)
Total number of events related to study drug 61 51 71 183
dcd D.1.1.1.1 50 (37.3%) 42 (31.3%) 51 (38.6%) 143 (35.8%)
cl B.1
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 49 (36.6%) 43 (32.6%) 139 (34.8%)
Total number of events related to study drug 56 60 62 178
dcd B.1.1.1.1 47 (35.1%) 49 (36.6%) 43 (32.6%) 139 (34.8%)
cl C.2
Total number of patients with at least one adverse event related to study drug 35 (26.1%) 48 (35.8%) 55 (41.7%) 138 (34.5%)
Total number of events related to study drug 48 53 65 166
dcd C.2.1.2.1 35 (26.1%) 48 (35.8%) 55 (41.7%) 138 (34.5%)
cl C.1
Total number of patients with at least one adverse event related to study drug 43 (32.1%) 46 (34.3%) 43 (32.6%) 132 (33.0%)
Total number of events related to study drug 55 63 64 182
dcd C.1.1.1.3 43 (32.1%) 46 (34.3%) 43 (32.6%) 132 (33.0%)
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.
lyt <-basic_table(show_colcounts =TRUE) %>%split_cols_by(var ="ARM") %>%analyze_num_patients(vars ="USUBJID",.stats =c("unique", "nonunique"),.labels =c(unique ="Total number of patients with at least one adverse event related to study drug",nonunique ="Overall total number of events related to study drug" ) ) %>%split_rows_by("AEBODSYS",child_labels ="visible",nested =FALSE,split_fun = split_fun,indent_mod =1L,label_pos ="topleft",split_label =obj_label(adae_f$AEBODSYS) ) %>%summarize_num_patients(var ="USUBJID",.stats =c("unique", "nonunique"),.labels =c(unique ="Total number of patients with at least one adverse event related to study drug",nonunique ="Total number of events related to study drug" ) ) %>%split_rows_by("AEHLT",child_labels ="visible",nested =TRUE,indent_mod =-1L,split_fun = split_fun,label_pos ="topleft",split_label =obj_label(adae_f$AEHLT) ) %>%summarize_num_patients(var ="USUBJID",.stats =c("unique", "nonunique"),.labels =c(unique ="Total number of patients with at least one adverse event related to study drug",nonunique ="Total number of events related to study drug" ) ) %>%count_occurrences(vars ="AEDECOD",.indent_mods =-1L ) %>%append_varlabels(adae_f, c("AEDECOD"), indent =2L)tbl2 <-build_table(lyt = lyt,df = adae_f,alt_counts_df = adsl) %>%prune_table()result <- tbl2 %>%sort_at_path(path =c("AEBODSYS"),scorefun = cont_n_allcols ) %>%sort_at_path(path =c("AEBODSYS", "*", "AEHLT"),scorefun = cont_n_allcols ) %>%sort_at_path(path =c("AEBODSYS", "*", "AEHLT", "*", "AEDECOD"),scorefun = score_occurrences )result
Body System or Organ Class
High Level Term A: Drug X B: Placebo C: Combination
Dictionary-Derived Term (N=134) (N=134) (N=132)
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
Total number of patients with at least one adverse event related to study drug 105 (78.4%) 108 (80.6%) 109 (82.6%)
Overall total number of events related to study drug 282 299 336
cl D.2
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 58 (43.3%) 57 (43.2%)
Total number of events related to study drug 62 72 74
hlt D.2.1.5
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 58 (43.3%) 57 (43.2%)
Total number of events related to study drug 62 72 74
dcd D.2.1.5.3 47 (35.1%) 58 (43.3%) 57 (43.2%)
cl D.1
Total number of patients with at least one adverse event related to study drug 50 (37.3%) 42 (31.3%) 51 (38.6%)
Total number of events related to study drug 61 51 71
hlt D.1.1.1
Total number of patients with at least one adverse event related to study drug 50 (37.3%) 42 (31.3%) 51 (38.6%)
Total number of events related to study drug 61 51 71
dcd D.1.1.1.1 50 (37.3%) 42 (31.3%) 51 (38.6%)
cl B.1
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 49 (36.6%) 43 (32.6%)
Total number of events related to study drug 56 60 62
hlt B.1.1.1
Total number of patients with at least one adverse event related to study drug 47 (35.1%) 49 (36.6%) 43 (32.6%)
Total number of events related to study drug 56 60 62
dcd B.1.1.1.1 47 (35.1%) 49 (36.6%) 43 (32.6%)
cl C.2
Total number of patients with at least one adverse event related to study drug 35 (26.1%) 48 (35.8%) 55 (41.7%)
Total number of events related to study drug 48 53 65
hlt C.2.1.2
Total number of patients with at least one adverse event related to study drug 35 (26.1%) 48 (35.8%) 55 (41.7%)
Total number of events related to study drug 48 53 65
dcd C.2.1.2.1 35 (26.1%) 48 (35.8%) 55 (41.7%)
cl C.1
Total number of patients with at least one adverse event related to study drug 43 (32.1%) 46 (34.3%) 43 (32.6%)
Total number of events related to study drug 55 63 64
hlt C.1.1.1
Total number of patients with at least one adverse event related to study drug 43 (32.1%) 46 (34.3%) 43 (32.6%)
Total number of events related to study drug 55 63 64
dcd C.1.1.1.3 43 (32.1%) 46 (34.3%) 43 (32.6%)
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.
Code
library(dplyr)library(tern)adsl <- random.cdisc.data::cadsladae <- random.cdisc.data::cadae# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels.adsl <-df_explicit_na(adsl)adae <-df_explicit_na(adae)adae_labels <-var_labels(adae)adae_f <- adae %>%filter(AEREL =="Y")var_labels(adae_f) <- adae_labels
library(teal.modules.clinical)## Data reproducible codedata <-teal_data()data <-within(data, { ADSL <- random.cdisc.data::cadsl ADAE <- random.cdisc.data::cadae# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. ADSL <-df_explicit_na(ADSL) ADAE <-df_explicit_na(ADAE)})datanames <-c("ADSL", "ADAE")datanames(data) <- datanamesjoin_keys(data) <- default_cdisc_join_keys[datanames]## Reusable Configuration For ModulesADAE <- data[["ADAE"]]## Setup Appapp <-init(data = data,modules =modules(tm_t_events(label ="Adverse Events Related to Study Drug",dataname ="ADAE",arm_var =choices_selected(c("ARM", "ARMCD"), "ARM"),llt =choices_selected(choices =variable_choices(ADAE, c("AETERM", "AEDECOD")),selected =c("AEDECOD") ),hlt =choices_selected(choices =variable_choices(ADAE, c("AEBODSYS", "AEHLT")),selected =c("AEBODSYS") ),add_total =FALSE,event_type ="adverse event related to study drug", # define event type here ) ),filter =teal_slices(teal_slice("ADAE", "AEREL", selected ="Y")) # related AEs only)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.
#| 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 codedata <- teal_data()data <- within(data, { ADSL <- random.cdisc.data::cadsl ADAE <- random.cdisc.data::cadae # Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels. ADSL <- df_explicit_na(ADSL) ADAE <- df_explicit_na(ADAE)})datanames <- c("ADSL", "ADAE")datanames(data) <- datanamesjoin_keys(data) <- default_cdisc_join_keys[datanames]## Reusable Configuration For ModulesADAE <- data[["ADAE"]]## Setup Appapp <- init( data = data, modules = modules( tm_t_events( label = "Adverse Events Related to Study Drug", dataname = "ADAE", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), llt = choices_selected( choices = variable_choices(ADAE, c("AETERM", "AEDECOD")), selected = c("AEDECOD") ), hlt = choices_selected( choices = variable_choices(ADAE, c("AEBODSYS", "AEHLT")), selected = c("AEBODSYS") ), add_total = FALSE, event_type = "adverse event related to study drug", # define event type here ) ), filter = teal_slices(teal_slice("ADAE", "AEREL", selected = "Y")) # related AEs only)shinyApp(app$ui, app$server)