-
-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add decorators to all TMC modules #1371
Comments
5 tasks
This was referenced Nov 26, 2024
This was referenced Nov 27, 2024
This was referenced Nov 28, 2024
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 28, 2024
Part of insightsengineering/teal#1371 WIP <details> <summary> Example with decorator </summary> ```r devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } app <- init( data = data, modules = modules( tm_g_ci( label = "Confidence Interval Plot", x_var = data_extract_spec( dataname = "ADSL", select = select_spec( choices = c("ARMCD", "BMRKR2"), selected = c("ARMCD"), multiple = FALSE, fixed = FALSE ) ), y_var = data_extract_spec( dataname = "ADLB", filter = list( filter_spec( vars = "PARAMCD", choices = levels(ADLB$PARAMCD), selected = levels(ADLB$PARAMCD)[1], multiple = FALSE, label = "Select lab:" ), filter_spec( vars = "AVISIT", choices = levels(ADLB$AVISIT), selected = levels(ADLB$AVISIT)[1], multiple = FALSE, label = "Select visit:" ) ), select = select_spec( label = "Analyzed Value", choices = c("AVAL", "CHG"), selected = "AVAL", multiple = FALSE, fixed = FALSE ) ), color = data_extract_spec( dataname = "ADSL", select = select_spec( label = "Color by variable", choices = c("SEX", "STRATA1", "STRATA2"), selected = c("STRATA1"), multiple = FALSE, fixed = FALSE ) ), decorators = list(caption_decorator(.var_to_replace = "plot")) ) ) ) shinyApp(app$ui, app$server) ``` </details> --------- Co-authored-by: Marcin <[email protected]> Co-authored-by: m7pr <[email protected]>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 28, 2024
Part of insightsengineering/teal#1371 This module also returns a plot from `cowplot`, and I am not sure if the example I got works well (I am not that familiar with it). <details> <summary>Draft of an example</summary> ````r devtools::load_all("../teal.reporter") devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) caption_decorator <- function(annotation = "I am a good decorator", var_to_decorate = "plot") { teal_transform_module( label = "Annotation", ui = function(id) shiny::textInput(shiny::NS(id, "annotation"), "Annotation", value = annotation), server = make_teal_transform_server( substitute({ var_to_decorate <- cowplot::add_sub(var_to_decorate, annotation) }, env = list(var_to_decorate = as.name(var_to_decorate))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADRS <- tmc_ex_adrs %>% mutate(AVALC = d_onco_rsp_label(AVALC) %>% with_label("Character Result/Finding")) %>% filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP") }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADRS <- data[["ADRS"]] arm_ref_comp <- list( ARM = list( ref = "B: Placebo", comp = c("A: Drug X", "C: Combination") ), ARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ) ) app <- init( data = data, modules = modules( tm_g_forest_rsp( label = "Forest Response", dataname = "ADRS", arm_var = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD")), "ARMCD" ), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADRS, "PARAMCD", "PARAM"), "INVET" ), subgroup_var = choices_selected( variable_choices(ADSL, names(ADSL)), c("BMRKR2", "SEX") ), strata_var = choices_selected( variable_choices(ADSL, c("STRATA1", "STRATA2")), "STRATA2" ), plot_height = c(600L, 200L, 2000L), default_responses = list( BESRSPI = list( rsp = c("Stable Disease (SD)", "Not Evaluable (NE)"), levels = c( "Complete Response (CR)", "Partial Response (PR)", "Stable Disease (SD)", "Progressive Disease (PD)", "Not Evaluable (NE)" ) ), INVET = list( rsp = c("Complete Response (CR)", "Partial Response (PR)"), levels = c( "Complete Response (CR)", "Not Evaluable (NE)", "Partial Response (PR)", "Progressive Disease (PD)", "Stable Disease (SD)" ) ), OVRINV = list( rsp = c("Progressive Disease (PD)", "Stable Disease (SD)"), levels = c("Progressive Disease (PD)", "Stable Disease (SD)", "Not Evaluable (NE)") ) ), decorators = list(caption_decorator()) ) ) ) shinyApp(app$ui, app$server) ``` </details> --------- Co-authored-by: Marcin <[email protected]> Co-authored-by: m7pr <[email protected]>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 28, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r devtools::load_all("../teal.reporter") devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) caption_decorator <- function(annotation = "I am a good decorator", var_to_decorate = "plot") { teal_transform_module( label = "Annotation", ui = function(id) shiny::textInput(shiny::NS(id, "annotation"), "Annotation", value = annotation), server = make_teal_transform_server( substitute({ var_to_decorate <- cowplot::add_sub(var_to_decorate, annotation) }, env = list(var_to_decorate = as.name(var_to_decorate))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADTTE <- tmc_ex_adtte ADSL$RACE <- droplevels(ADSL$RACE) %>% with_label("Race") }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADTTE <- data[["ADTTE"]] arm_ref_comp <- list( ARM = list( ref = "B: Placebo", comp = c("A: Drug X", "C: Combination") ), ARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ) ) app <- init( data = data, modules = modules( tm_g_forest_tte( label = "Forest Survival", dataname = "ADTTE", arm_var = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD")), "ARMCD" ), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), subgroup_var = choices_selected( variable_choices(ADSL, names(ADSL)), c("BMRKR2", "SEX") ), strata_var = choices_selected( variable_choices(ADSL, c("STRATA1", "STRATA2")), "STRATA2" ), decorators = list(caption_decorator()) ) ) ) shinyApp(app$ui, app$server) ``` </details>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 28, 2024
Part of insightsengineering/teal#1371 Alternative to #1259 <details><summary> Working Example </summary> ```r devtools::load_all("../teal.reporter") devtools::load_all("../teal") devtools::load_all(".") insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADQS <- tmc_ex_adqs %>% filter(ABLFL != "Y" & ABLFL2 != "Y") %>% mutate( AVISIT = as.factor(AVISIT), AVISITN = rank(AVISITN) %>% as.factor() %>% as.numeric() %>% as.factor(), AVALBIN = AVAL < 50 # Just as an example to get a binary endpoint. ) %>% droplevels() }) join_keys(data) <- default_cdisc_join_keys[names(data)] app <- init( data = data, modules = modules( tm_a_gee( label = "GEE", dataname = "ADQS", aval_var = choices_selected("AVALBIN", fixed = TRUE), id_var = choices_selected(c("USUBJID", "SUBJID"), "USUBJID"), arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), visit_var = choices_selected(c("AVISIT", "AVISITN"), "AVISIT"), paramcd = choices_selected( choices = value_choices(data[["ADQS"]], "PARAMCD", "PARAM"), selected = "FKSI-FWB" ), cov_var = choices_selected(c("BASE", "AGE", "SEX", "BASE:AVISIT"), NULL), decorators = list(insert_rrow_decorator("Hello world", "table")) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ``` </details>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 28, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl %>% slice(1:20) %>% df_explicit_na() ADLB <- tmc_ex_adlb %>% filter(USUBJID %in% ADSL$USUBJID) %>% df_explicit_na() %>% filter(AVISIT != "SCREENING") }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } app <- init( data = data, modules = modules( tm_g_ipp( label = "Individual Patient Plot", dataname = "ADLB", arm_var = choices_selected( value_choices(ADLB, "ARMCD"), "ARM A" ), paramcd = choices_selected( value_choices(ADLB, "PARAMCD"), "ALT" ), aval_var = choices_selected( variable_choices(ADLB, c("AVAL", "CHG")), "AVAL" ), avalu_var = choices_selected( variable_choices(ADLB, c("AVALU")), "AVALU", fixed = TRUE ), id_var = choices_selected( variable_choices(ADLB, c("USUBJID")), "USUBJID", fixed = TRUE ), visit_var = choices_selected( variable_choices(ADLB, c("AVISIT")), "AVISIT" ), baseline_var = choices_selected( variable_choices(ADLB, c("BASE")), "BASE", fixed = TRUE ), add_baseline_hline = FALSE, separate_by_obs = FALSE, decorators = list(caption_decorator(.var_to_replace = "plot")) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ``` </details>
This was referenced Nov 28, 2024
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 29, 2024
Part of insightsengineering/teal#1371 <details> <summary>Example using cowplot::add_sub with ggplot2</summary> ```r devtools::load_all("../teal.modules.general") devtools::load_all("../teal.reporter") devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) data <- teal_data() data <- within(data, { ADAE <- tmc_ex_adae ADSL <- tmc_ex_adsl %>% filter(USUBJID %in% ADAE$USUBJID) ADCM <- tmc_ex_adcm %>% mutate( CMSTDY = case_when( CMCAT == "medcl B" ~ 20, CMCAT == "medcl C" ~ 150, TRUE ~ 1 ) %>% with_label("Study Day of Start of Medication"), CMENDY = case_when( CMCAT == "medcl B" ~ 700, CMCAT == "medcl C" ~ 1000, TRUE ~ 500 ) %>% with_label("Study Day of End of Medication"), CMASTDTM = ASTDTM, CMAENDTM = AENDTM ) }) join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADAE", "ADCM")] adcm_keys <- c("STUDYID", "USUBJID", "ASTDTM", "CMSEQ", "ATC1", "ATC2", "ATC3", "ATC4") join_keys(data)["ADCM", "ADCM"] <- adcm_keys join_keys(data)["ADAE", "ADCM"] <- c("STUDYID", "USUBJID") caption_decorator <- function(annotation = "I am a good decorator", var_to_decorate = "plot") { teal_transform_module( label = "Annotation", ui = function(id) shiny::textInput(shiny::NS(id, "annotation"), "Annotation", value = annotation), server = make_teal_transform_server( substitute({ var_to_decorate <- cowplot::add_sub(var_to_decorate, annotation) }, env = list(var_to_decorate = as.name(var_to_decorate))) ) ) } app <- init( data = data, modules = modules( tm_g_pp_patient_timeline( label = "Patient Timeline", dataname_adae = "ADAE", dataname_adcm = "ADCM", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), cmdecod = choices_selected( choices = variable_choices(data[["ADCM"]], "CMDECOD"), selected = "CMDECOD", ), aeterm = choices_selected( choices = variable_choices(data[["ADAE"]], "AETERM"), selected = c("AETERM") ), aetime_start = choices_selected( choices = variable_choices(data[["ADAE"]], "ASTDTM"), selected = c("ASTDTM") ), aetime_end = choices_selected( choices = variable_choices(data[["ADAE"]], "AENDTM"), selected = c("AENDTM") ), dstime_start = choices_selected( choices = variable_choices(data[["ADCM"]], "CMASTDTM"), selected = c("CMASTDTM") ), dstime_end = choices_selected( choices = variable_choices(data[["ADCM"]], "CMAENDTM"), selected = c("CMAENDTM") ), aerelday_start = choices_selected( choices = variable_choices(data[["ADAE"]], "ASTDY"), selected = c("ASTDY") ), aerelday_end = choices_selected( choices = variable_choices(data[["ADAE"]], "AENDY"), selected = c("AENDY") ), dsrelday_start = choices_selected( choices = variable_choices(data[["ADCM"]], "ASTDY"), selected = c("ASTDY") ), dsrelday_end = choices_selected( choices = variable_choices(data[["ADCM"]], "AENDY"), selected = c("AENDY") ), decorators = list(caption_decorator()) ) ) ) shinyApp(app$ui, app$server) ``` </details> --------- Co-authored-by: m7pr <[email protected]>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 29, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r devtools::load_all("../teal.reporter") devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) data <- teal_data() data <- within(data, { ADCM <- tmc_ex_adcm ADSL <- tmc_ex_adsl %>% filter(USUBJID %in% ADCM$USUBJID) ADCM$CMASTDTM <- ADCM$ASTDTM ADCM$CMAENDTM <- ADCM$AENDTM }) join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADCM")] adcm_keys <- c("STUDYID", "USUBJID", "ASTDTM", "CMSEQ", "ATC1", "ATC2", "ATC3", "ATC4") join_keys(data)["ADCM", "ADCM"] <- adcm_keys ADSL <- data[["ADSL"]] ADCM <- data[["ADCM"]] caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } head_decorator <- function(default_value = 6, .var_to_replace = "object") { teal_transform_module( label = "Head", ui = function(id) shiny::numericInput(shiny::NS(id, "n"), "N rows", value = default_value), server = make_teal_transform_server( substitute({ .var_to_replace <- utils::head(.var_to_replace, n = n) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } app <- init( data = data, modules = modules( tm_g_pp_therapy( label = "Therapy", dataname = "ADCM", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), atirel = choices_selected( choices = variable_choices(ADCM, "ATIREL"), selected = c("ATIREL") ), cmdecod = choices_selected( choices = variable_choices(ADCM, "CMDECOD"), selected = "CMDECOD" ), cmindc = choices_selected( choices = variable_choices(ADCM, "CMINDC"), selected = "CMINDC" ), cmdose = choices_selected( choices = variable_choices(ADCM, "CMDOSE"), selected = "CMDOSE" ), cmtrt = choices_selected( choices = variable_choices(ADCM, "CMTRT"), selected = "CMTRT" ), cmdosu = choices_selected( choices = variable_choices(ADCM, "CMDOSU"), selected = c("CMDOSU") ), cmroute = choices_selected( choices = variable_choices(ADCM, "CMROUTE"), selected = "CMROUTE" ), cmdosfrq = choices_selected( choices = variable_choices(ADCM, "CMDOSFRQ"), selected = "CMDOSFRQ" ), cmstdy = choices_selected( choices = variable_choices(ADCM, "ASTDY"), selected = "ASTDY" ), cmendy = choices_selected( choices = variable_choices(ADCM, "AENDY"), selected = "AENDY" ), decorators = list(plot = caption_decorator('Marcin', 'plot'), table = head_decorator(2, 'table')) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ``` </details>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 29, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADVS <- tmc_ex_advs }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADVS <- data[["ADVS"]] change_theme_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Theme", server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::theme_void() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } app <- init( data = data, modules = modules( tm_g_pp_vitals( label = "Vitals", dataname = "ADVS", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), paramcd = choices_selected( choices = variable_choices(ADVS, "PARAMCD"), selected = "PARAMCD" ), xaxis = choices_selected( choices = variable_choices(ADVS, "ADY"), selected = "ADY" ), aval_var = choices_selected( choices = variable_choices(ADVS, "AVAL"), selected = "AVAL" )#, #decorators = list(plot = change_theme_decorator(TRUE, "plot")) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) }devtools::load_all("../teal") devtools::load_all(".") library(nestcolor) library(dplyr) library(forcats) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb %>% mutate(AVISIT == fct_reorder(AVISIT, AVISITN, min)) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] change_theme_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Theme", server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::theme_void() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } app <- init( data = data, modules = modules( tm_g_lineplot( label = "Line Plot", dataname = "ADLB", strata = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD", "ACTARMCD")), "ARM" ), y = choices_selected( variable_choices(ADLB, c("AVAL", "BASE", "CHG", "PCHG")), "AVAL" ), param = choices_selected( value_choices(ADLB, "PARAMCD", "PARAM"), "ALT" ), decorators = list(plot = change_theme_decorator(TRUE, "plot")) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ``` </details> --------- Co-authored-by: André Veríssimo <[email protected]>
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Nov 29, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r devtools::load_all("../teal") devtools::load_all(".") insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb %>% mutate( ONTRTFL = case_when( AVISIT %in% c("SCREENING", "BASELINE") ~ "", TRUE ~ "Y" ) %>% with_label("On Treatment Record Flag") ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] app <- init( data = data, modules = modules( tm_t_abnormality( label = "Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), add_total = FALSE, by_vars = choices_selected( choices = variable_choices(ADLB, subset = c("LBCAT", "PARAM", "AVISIT")), selected = c("LBCAT", "PARAM"), keep_order = TRUE ), baseline_var = choices_selected( variable_choices(ADLB, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), grade = choices_selected( choices = variable_choices(ADLB, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), abnormal = list(low = "LOW", high = "HIGH"), exclude_base_abn = FALSE, decorators = list(insert_rrow_decorator("I am a good new row")) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ``` </details> --------- Co-authored-by: Lluís Revilla <[email protected]> Co-authored-by: André Veríssimo <[email protected]>
This was referenced Dec 5, 2024
m7pr
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 9, 2024
Part of insightsengineering/teal#1371 <details><summary> Working Example </summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) library(nestcolor) library(dplyr) data <- teal_data() data <- within(data, { ADAE <- tmc_ex_adae ADSL <- tmc_ex_adsl %>% filter(USUBJID %in% ADAE$USUBJID) ADAE$ASTDY <- structure( as.double(ADAE$ASTDY, unit = attr(ADAE$ASTDY, "units", exact = TRUE)), label = attr(ADAE$ASTDY, "label", exact = TRUE) ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADAE <- data[["ADAE"]] caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } head_decorator <- function(default_value = 6, .var_to_replace = "object") { teal_transform_module( label = "Head", ui = function(id) shiny::numericInput(shiny::NS(id, "n"), "N rows", value = default_value), server = make_teal_transform_server( substitute({ .var_to_replace <- utils::head(.var_to_replace, n = n) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } app <- init( data = data, modules = modules( tm_g_pp_adverse_events( label = "Adverse Events", dataname = "ADAE", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), aeterm = choices_selected( choices = variable_choices(ADAE, "AETERM"), selected = "AETERM" ), tox_grade = choices_selected( choices = variable_choices(ADAE, "AETOXGR"), selected = "AETOXGR" ), causality = choices_selected( choices = variable_choices(ADAE, "AEREL"), selected = "AEREL" ), outcome = choices_selected( choices = variable_choices(ADAE, "AEOUT"), selected = "AEOUT" ), action = choices_selected( choices = variable_choices(ADAE, "AEACN"), selected = "AEACN" ), time = choices_selected( choices = variable_choices(ADAE, "ASTDY"), selected = "ASTDY" ), decod = NULL, decorators = list(plot = caption_decorator('Marcin', 'plot'), table = head_decorator(2, 'table')) ) ) ) |> shiny::runApp() ``` </details> --------- Signed-off-by: Marcin <[email protected]> Co-authored-by: André Veríssimo <[email protected]>
llrs-roche
pushed a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 9, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below rlisting_footer <- function(default_footer = "I am a good footer", .var_to_replace = "table_listing") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "footer"), "footer", value = default_footer), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADMH <- tmc_ex_admh }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADMH <- data[["ADMH"]] app <- init( data = data, modules = modules( tm_t_pp_medical_history( label = "Medical History", dataname = "ADMH", parentname = "ADSL", patient_col = "USUBJID", mhterm = choices_selected( choices = variable_choices(ADMH, c("MHTERM")), selected = "MHTERM" ), mhbodsys = choices_selected( choices = variable_choices(ADMH, "MHBODSYS"), selected = "MHBODSYS" ), mhdistat = choices_selected( choices = variable_choices(ADMH, "MHDISTAT"), selected = "MHDISTAT" ), decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADRS <- tmc_ex_adrs %>% filter(PARAMCD %in% c("BESRSPI", "INVET")) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADRS <- data[["ADRS"]] arm_ref_comp <- list( ACTARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ), ARM = list( ref = "B: Placebo", comp = c("A: Drug X", "C: Combination") ) ) init( data = data, modules = modules( tm_t_logistic( label = "Logistic Regression", dataname = "ADRS", arm_var = choices_selected( choices = variable_choices(ADRS, c("ARM", "ARMCD")), selected = "ARM" ), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(ADRS, "PARAMCD", "PARAM"), selected = "BESRSPI" ), cov_var = choices_selected( choices = c("SEX", "AGE", "BMRKR1", "BMRKR2"), selected = "SEX" ), decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } # Preparation of the test case - use `EOSDY` and `DCSREAS` variables to demonstrate missing data. data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADSL$EOSDY[1] <- NA_integer_ }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] app <- init( data = data, modules = modules( tm_t_summary( label = "Demographic Table", dataname = "ADSL", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), add_total = TRUE, summarize_vars = choices_selected( c("SEX", "RACE", "BMRKR2", "EOSDY", "DCSREAS", "AGE"), c("SEX", "RACE") ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADAE <- tmc_ex_adae .names_baskets <- grep("^(SMQ|CQ).*NAM$", names(ADAE), value = TRUE) .names_scopes <- grep("^SMQ.*SC$", names(ADAE), value = TRUE) .cs_baskets <- choices_selected( choices = variable_choices(ADAE, subset = .names_baskets), selected = .names_baskets ) .cs_scopes <- choices_selected( choices = variable_choices(ADAE, subset = .names_scopes), selected = .names_scopes, fixed = TRUE ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] app <- init( data = data, modules = modules( tm_t_smq( label = "Adverse Events by SMQ Table", dataname = "ADAE", arm_var = choices_selected( choices = variable_choices(data[["ADSL"]], subset = c("ARM", "SEX")), selected = "ARM" ), add_total = FALSE, baskets = data[[".cs_baskets"]], scopes = data[[".cs_scopes"]], llt = choices_selected( choices = variable_choices(data[["ADAE"]], subset = c("AEDECOD")), selected = "AEDECOD" ), decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] init( data = data, modules = modules( tm_t_shift_by_grade( label = "Grade Laboratory Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), worst_flag_var = choices_selected( choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")), selected = c("WGRLOVFL") ), worst_flag_indicator = choices_selected( value_choices(ADLB, "WGRLOVFL"), selected = "Y", fixed = TRUE ), anl_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("ATOXGR")), selected = c("ATOXGR"), fixed = TRUE ), base_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("BTOXGR")), selected = c("BTOXGR"), fixed = TRUE ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ) ), filter = teal_slices(teal_slice("ADSL", "SAFFL", selected = "Y")) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] app <- init( data = data, modules = modules( tm_t_summary_by( label = "Summary by Row Groups Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, c("ARM", "ARMCD")), selected = "ARM" ), add_total = TRUE, by_vars = choices_selected( choices = variable_choices(ADLB, c("PARAM", "AVISIT")), selected = c("AVISIT") ), summarize_vars = choices_selected( choices = variable_choices(ADLB, c("AVAL", "CHG")), selected = c("AVAL") ), useNA = "ifany", paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADEG <- tmc_ex_adeg }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADEG <- data[["ADEG"]] init( data = data, modules = modules( tm_t_shift_by_arm( label = "Shift by Arm Table", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "HR" ), visit_var = choices_selected( value_choices(ADEG, "AVISIT"), selected = "POST-BASELINE MINIMUM" ), aval_var = choices_selected( variable_choices(ADEG, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), baseline_var = choices_selected( variable_choices(ADEG, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 10, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADEG <- tmc_ex_adeg }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADEG <- data[["ADEG"]] init( data = data, modules = modules( tm_t_shift_by_arm_by_worst( label = "Shift by Arm Table", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "ECGINTP" ), worst_flag_var = choices_selected( variable_choices(ADEG, c("WORS02FL", "WORS01FL")), selected = "WORS02FL" ), worst_flag = choices_selected( value_choices(ADEG, "WORS02FL"), selected = "Y", fixed = TRUE ), aval_var = choices_selected( variable_choices(ADEG, c("AVALC", "ANRIND")), selected = "AVALC" ), baseline_var = choices_selected( variable_choices(ADEG, c("BASEC", "BNRIND")), selected = "BASEC" ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
llrs-roche
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 11, 2024
Part of insightsengineering/teal#1371 <details> <summary>Example with decorator</summary> ```r devtools::load_all("../teal") devtools::load_all("../tern") devtools::load_all(".") insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADEX <- tmc_ex_adex set.seed(1, kind = "Mersenne-Twister") .labels <- col_labels(ADEX, fill = FALSE) ADEX <- ADEX %>% distinct(USUBJID, .keep_all = TRUE) %>% mutate( PARAMCD = "TDURD", PARAM = "Overall duration (days)", AVAL = sample(x = seq(1, 200), size = n(), replace = TRUE), AVALU = "Days" ) %>% bind_rows(ADEX) col_labels(ADEX) <- .labels }) join_keys(data) <- default_cdisc_join_keys[names(data)] app <- init( data = data, modules = modules( tm_t_exposure( label = "Duration of Exposure Table", dataname = "ADEX", paramcd = choices_selected( choices = value_choices(data[["ADEX"]], "PARAMCD", "PARAM"), selected = "TDURD" ), col_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("SEX", "ARM")), selected = "SEX" ), row_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("RACE", "REGION1", "STRATA1", "SEX")), selected = "RACE" ), parcat = choices_selected( choices = value_choices(data[["ADEX"]], "PARCAT2"), selected = "Drug A" ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ) ), filter = teal_slices(teal_slice("ADSL", "SAFFL", selected = "Y")) ) shinyApp(app$ui, app$server) ``` </details> Note: I placed the decorated right above some options to add additional columns and rows. Perhaps we need to review where to place it. I would group these three options in a single panel --------- Signed-off-by: Lluís Revilla <[email protected]> Co-authored-by: André Veríssimo <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 11, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below rlisting_footer <- function(default_footer = "I am a good footer", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "footer"), "footer", value = default_footer), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } dt_decorator <- function(.color1 = "#f9f9f9", .color2 = "#f0f0f0", .var_to_replace = "table") { teal_transform_module( label = "Table color", ui = function(id) { selectInput( NS(id, "style"), "Table Style", choices = c("Default", "Color1", "Color2"), selected = "Default" ) }, server = function(id, data) { moduleServer(id, function(input, output, session) { logger::log_info("🔵 Table row color called to action!", namespace = "teal.modules.general") reactive({ req(data(), input$style) logger::log_info("changing the Table row color '{input$style}'", namespace = "teal.modules.general") teal.code::eval_code(data(), substitute({ .var_to_replace <- switch( style, "Color1" = DT::formatStyle( .var_to_replace, columns = attr(.var_to_replace$x, "colnames")[-1], target = "row", backgroundColor = .color1 ), "Color2" = DT::formatStyle( .var_to_replace, columns = attr(.var_to_replace$x, "colnames")[-1], target = "row", backgroundColor = .color2 ), .var_to_replace ) }, env = list( style = input$style, .var_to_replace = as.name(.var_to_replace), .color1 = .color1, .color2 = .color2 ))) }) }) } ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADLB <- tmc_ex_adlb }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADLB <- data[["ADLB"]] init( data = data, modules = modules( tm_t_pp_laboratory( label = "Vitals", dataname = "ADLB", patient_col = "USUBJID", paramcd = choices_selected( choices = variable_choices(ADLB, "PARAMCD"), selected = "PARAMCD" ), param = choices_selected( choices = variable_choices(ADLB, "PARAM"), selected = "PARAM" ), timepoints = choices_selected( choices = variable_choices(ADLB, "ADY"), selected = "ADY" ), anrind = choices_selected( choices = variable_choices(ADLB, "ANRIND"), selected = "ANRIND" ), aval_var = choices_selected( choices = variable_choices(ADLB, "AVAL"), selected = "AVAL" ), avalu_var = choices_selected( choices = variable_choices(ADLB, "AVALU"), selected = "AVALU" ), decorators = list( table_listing = rlisting_footer() ) ) ) ) |> shiny::runApp() ``` </details>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 11, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rlisting_footer_decorator <- function(default_caption = "I am a good new footer", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_footer"), "New footer", value = default_caption), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- new_footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] init( data = data, modules = modules( tm_t_pp_basic_info( label = "Basic Info", dataname = "ADSL", patient_col = "USUBJID", vars = choices_selected(choices = variable_choices(ADSL), selected = c("ARM", "AGE", "SEX", "COUNTRY", "RACE", "EOSSTT")), decorators = list( table = insert_rlisting_footer_decorator(.var_to_replace = "table") ) ) ) ) |> shiny::runApp() ``` </details>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 11, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below rlisting_footer <- function(default_footer = "I am a good footer", .var_to_replace = "table_listing") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "footer"), "footer", value = default_footer), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } library(dplyr) data <- teal_data() data <- within(data, { ADCM <- tmc_ex_adcm ADSL <- tmc_ex_adsl %>% filter(USUBJID %in% ADCM$USUBJID) ADCM$CMASTDTM <- ADCM$ASTDTM ADCM$CMAENDTM <- ADCM$AENDTM }) join_keys(data) <- default_cdisc_join_keys[names(data)] adcm_keys <- c("STUDYID", "USUBJID", "ASTDTM", "CMSEQ", "ATC1", "ATC2", "ATC3", "ATC4") join_keys(data)["ADCM", "ADCM"] <- adcm_keys ADSL <- data[["ADSL"]] ADCM <- data[["ADCM"]] init( data = data, modules = modules( tm_t_pp_prior_medication( label = "Prior Medication", dataname = "ADCM", parentname = "ADSL", patient_col = "USUBJID", atirel = choices_selected( choices = variable_choices(ADCM, "ATIREL"), selected = "ATIREL" ), cmdecod = choices_selected( choices = variable_choices(ADCM, "CMDECOD"), selected = "CMDECOD" ), cmindc = choices_selected( choices = variable_choices(ADCM, "CMINDC"), selected = "CMINDC" ), cmstdy = choices_selected( choices = variable_choices(ADCM, "ASTDY"), selected = "ASTDY" ), decorators = list( table = rlisting_footer(.var_to_replace = "table") ) ) ) ) |> shiny::runApp() ``` </details>
llrs-roche
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 11, 2024
Part of insightsengineering/teal#1371 <details> <summary>Example with decorators</summary> ```r load_all("../teal") load_all(".") library(dplyr) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl .lbls_adae <- col_labels(tmc_ex_adae) ADAE <- tmc_ex_adae %>% mutate_if(is.character, as.factor) #' be certain of having factors col_labels(ADAE) <- .lbls_adae }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADAE <- data[["ADAE"]] insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } app <- init( data = data, modules = modules( tm_t_events_by_grade( label = "Adverse Events by Grade Table", 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", "AESOC")), selected = "AEBODSYS" ), grade = choices_selected( choices = variable_choices(ADAE, c("AETOXGR", "AESEV")), selected = "AETOXGR" ), decorators = list(insert_rrow_decorator()) ) ) ) shinyApp(app$ui, app$server) ``` </details> --------- Signed-off-by: Lluís Revilla <[email protected]> Co-authored-by: André Veríssimo <[email protected]> Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 12, 2024
Part of insightsengineering/teal#1371 <details> <summary>Working example</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } add_title_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Theme", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Add title?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::ggtitle("Title added by decorator") }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } library(dplyr) arm_ref_comp <- list( ARMCD = list( ref = "ARM B", comp = c("ARM A", "ARM C") ) ) data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl ADQS <- tmc_ex_adqs %>% filter(ABLFL != "Y" & ABLFL2 != "Y") %>% filter(AVISIT %in% c("WEEK 1 DAY 8", "WEEK 2 DAY 15", "WEEK 3 DAY 22")) %>% mutate( AVISIT = as.factor(AVISIT), AVISITN = rank(AVISITN) %>% as.factor() %>% as.numeric() %>% as.factor() #' making consecutive numeric factor ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] init( data = data, modules = modules( tm_a_mmrm( label = "MMRM", dataname = "ADQS", aval_var = choices_selected(c("AVAL", "CHG"), "AVAL"), id_var = choices_selected(c("USUBJID", "SUBJID"), "USUBJID"), arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), visit_var = choices_selected(c("AVISIT", "AVISITN"), "AVISIT"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(data[["ADQS"]], "PARAMCD", "PARAM"), selected = "FKSI-FWB" ), cov_var = choices_selected(c("BASE", "AGE", "SEX", "BASE:AVISIT"), NULL), decorators = list( lsmeans_table = insert_rrow_decorator("A", .var_to_replace = "lsmeans_table") , lsmeans_plot = add_title_decorator("B", .var_to_replace = "lsmeans_plot") , covariance_table = insert_rrow_decorator("C", .var_to_replace = "covariance_table") , fixed_effects_table = insert_rrow_decorator("D", .var_to_replace = "fixed_effects_table") , diagnostic_table = insert_rrow_decorator(.var_to_replace = "diagnostic_table") , diagnostic_plot = add_title_decorator(.var_to_replace = "diagnostic_plot") ) ) ) ) |> shiny::runApp() ``` </details> --------- Co-authored-by: Marcin <[email protected]>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 16, 2024
Part of insightsengineering/teal#1371 ### Example app with all modules / decorators <details> <summary>Example app</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Decorators ------------------------------------------------------------------ insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New rtables row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } add_title_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Title", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Add title?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::ggtitle("Title added by decorator") }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } change_theme_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Theme", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Apply dark theme?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::theme_dark() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } add_cowplot_title_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Cowplot title", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Add title?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::ggtitle("Title added by decorator") + cowplot::theme_cowplot() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } rlisting_footer <- function(default_footer = "I am a good footer", .var_to_replace = "table_listing") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "footer"), "footer", value = default_footer), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } # End of decorators ----------------------------------------------------------- library(dplyr) # arm_ref_comp <- list(ARMCD = list(ref = "ARM B", comp = c("ARM A", "ARM C"))) arm_ref_comp <- list( ACTARMCD = list(ref = "ARM B", comp = c("ARM A", "ARM C")), ARM = list(ref = "B: Placebo", comp = c("A: Drug X", "C: Combination")) ) data <- within(teal_data(), { ADSL <- tmc_ex_adsl |> mutate(ITTFL = factor("Y") |> with_label("Intent-To-Treat Population Flag")) |> mutate(DTHFL = case_when(!is.na(DTHDT) ~ "Y", TRUE ~ "") |> with_label("Subject Death Flag")) ADAE <- tmc_ex_adae |> filter(!((AETOXGR == 1) & (AESEV == "MILD") & (ARM == "A: Drug X"))) ADAE$ASTDY <- structure( as.double(ADAE$ASTDY, unit = attr(ADAE$ASTDY, "units", exact = TRUE)), label = attr(ADAE$ASTDY, "label", exact = TRUE) ) .lbls_adae <- col_labels(tmc_ex_adae) ADAE <- tmc_ex_adae %>% mutate_if(is.character, as.factor) #' be certain of having factors col_labels(ADAE) <- .lbls_adae ADTTE <- tmc_ex_adtte ADLB <- tmc_ex_adlb |> mutate(AVISIT == forcats::fct_reorder(AVISIT, AVISITN, min)) |> mutate( ONTRTFL = case_when( AVISIT %in% c("SCREENING", "BASELINE") ~ "", TRUE ~ "Y" ) |> with_label("On Treatment Record Flag") ) ADVS <- tmc_ex_advs ADRS <- tmc_ex_adrs |> mutate( AVALC = d_onco_rsp_label(AVALC) |> with_label("Character Result/Finding") ) |> filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP") |> filter(PARAMCD %in% c("BESRSPI", "INVET")) ADAETTE <- tmc_ex_adaette %>% filter(PARAMCD %in% c("AETTE1", "AETTE2", "AETTE3")) %>% mutate(is_event = CNSR == 0) %>% mutate(n_events = as.integer(is_event)) .add_event_flags <- function(dat) { dat <- dat %>% mutate( TMPFL_SER = AESER == "Y", TMPFL_REL = AEREL == "Y", TMPFL_GR5 = AETOXGR == "5", TMP_SMQ01 = !is.na(SMQ01NAM), TMP_SMQ02 = !is.na(SMQ02NAM), TMP_CQ01 = !is.na(CQ01NAM) ) column_labels <- list( TMPFL_SER = "Serious AE", TMPFL_REL = "Related AE", TMPFL_GR5 = "Grade 5 AE", TMP_SMQ01 = aesi_label(dat[["SMQ01NAM"]], dat[["SMQ01SC"]]), TMP_SMQ02 = aesi_label("Y.9.9.9.9/Z.9.9.9.9 AESI"), TMP_CQ01 = aesi_label(dat[["CQ01NAM"]]) ) col_labels(dat)[names(column_labels)] <- as.character(column_labels) dat } ADEX <- tmc_ex_adex set.seed(1, kind = "Mersenne-Twister") .labels <- col_labels(ADEX, fill = FALSE) ADEX <- ADEX %>% distinct(USUBJID, .keep_all = TRUE) %>% mutate( PARAMCD = "TDURD", PARAM = "Overall duration (days)", AVAL = sample(x = seq(1, 200), size = n(), replace = TRUE), AVALU = "Days" ) %>% bind_rows(ADEX) col_labels(ADEX) <- .labels ADCM <- tmc_ex_adcm ADMH <- tmc_ex_admh ADCM$CMASTDTM <- ADCM$ASTDTM ADCM$CMAENDTM <- ADCM$AENDTM ADEG <- tmc_ex_adeg # smq .names_baskets <- grep("^(SMQ|CQ).*NAM$", names(ADAE), value = TRUE) .names_scopes <- grep("^SMQ.*SC$", names(ADAE), value = TRUE) .cs_baskets <- choices_selected( choices = variable_choices(ADAE, subset = .names_baskets), selected = .names_baskets ) .cs_scopes <- choices_selected( choices = variable_choices(ADAE, subset = .names_scopes), selected = .names_scopes, fixed = TRUE ) # summary ADSL$EOSDY[1] <- NA_integer_ }) join_keys(data) <- default_cdisc_join_keys[names(data)] adcm_keys <- c("STUDYID", "USUBJID", "ASTDTM", "CMSEQ", "ATC1", "ATC2", "ATC3", "ATC4") join_keys(data)["ADCM", "ADCM"] <- adcm_keys # Use in choices selected ----------------------------------------------------- ADSL <- data[["ADSL"]] ADQS <- data[["ADQS"]] ADAE <- data[["ADAE"]] ADTTE <- data[["ADTTE"]] ADLB <- data[["ADLB"]] ADAE <- data[["ADAE"]] ADVS <- data[["ADVS"]] ADRS <- data[["ADRS"]] ADAETTE <- data[["ADAETTE"]] ADEX <- data[["ADEX"]] ADCM <- data[["ADCM"]] ADMH <- data[["ADMH"]] ADEG <- data[["ADEG"]] # Init ------------------------------------------------------------------------ init( data = data, modules = modules( # ------------------------------------------------------------------------- tm_t_summary_by( label = "Summary by Row Groups Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, c("ARM", "ARMCD")), selected = "ARM" ), add_total = TRUE, by_vars = choices_selected( choices = variable_choices(ADLB, c("PARAM", "AVISIT")), selected = c("AVISIT") ), summarize_vars = choices_selected( choices = variable_choices(ADLB, c("AVAL", "CHG")), selected = c("AVAL") ), useNA = "ifany", paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_smq( label = "Adverse Events by SMQ Table", dataname = "ADAE", arm_var = choices_selected( choices = variable_choices(data[["ADSL"]], subset = c("ARM", "SEX")), selected = "ARM" ), add_total = FALSE, baskets = data[[".cs_baskets"]], scopes = data[[".cs_scopes"]], llt = choices_selected( choices = variable_choices(data[["ADAE"]], subset = c("AEDECOD")), selected = "AEDECOD" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_grade( label = "Grade Laboratory Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), worst_flag_var = choices_selected( choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")), selected = c("WGRLOVFL") ), worst_flag_indicator = choices_selected( value_choices(ADLB, "WGRLOVFL"), selected = "Y", fixed = TRUE ), anl_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("ATOXGR")), selected = c("ATOXGR"), fixed = TRUE ), base_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("BTOXGR")), selected = c("BTOXGR"), fixed = TRUE ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_arm( label = "Shift by Arm Table", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "HR" ), visit_var = choices_selected( value_choices(ADEG, "AVISIT"), selected = "POST-BASELINE MINIMUM" ), aval_var = choices_selected( variable_choices(ADEG, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), baseline_var = choices_selected( variable_choices(ADEG, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_arm_by_worst( label = "Shift by Arm Table (by worst)", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "ECGINTP" ), worst_flag_var = choices_selected( variable_choices(ADEG, c("WORS02FL", "WORS01FL")), selected = "WORS02FL" ), worst_flag = choices_selected( value_choices(ADEG, "WORS02FL"), selected = "Y", fixed = TRUE ), aval_var = choices_selected( variable_choices(ADEG, c("AVALC", "ANRIND")), selected = "AVALC" ), baseline_var = choices_selected( variable_choices(ADEG, c("BASEC", "BNRIND")), selected = "BASEC" ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_pp_prior_medication( label = "Prior Medication", dataname = "ADCM", parentname = "ADSL", patient_col = "USUBJID", atirel = choices_selected( choices = variable_choices(ADCM, "ATIREL"), selected = "ATIREL" ), cmdecod = choices_selected( choices = variable_choices(ADCM, "CMDECOD"), selected = "CMDECOD" ), cmindc = choices_selected( choices = variable_choices(ADCM, "CMINDC"), selected = "CMINDC" ), cmstdy = choices_selected( choices = variable_choices(ADCM, "ASTDY"), selected = "ASTDY" ), decorators = list( table = rlisting_footer(.var_to_replace = "table") ) ), # ------------------------------------------------------------------------- tm_t_pp_medical_history( label = "Medical History", dataname = "ADMH", parentname = "ADSL", patient_col = "USUBJID", mhterm = choices_selected( choices = variable_choices(ADMH, c("MHTERM")), selected = "MHTERM" ), mhbodsys = choices_selected( choices = variable_choices(ADMH, "MHBODSYS"), selected = "MHBODSYS" ), mhdistat = choices_selected( choices = variable_choices(ADMH, "MHDISTAT"), selected = "MHDISTAT" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_pp_laboratory( label = "Vitals", dataname = "ADLB", patient_col = "USUBJID", paramcd = choices_selected( choices = variable_choices(ADLB, "PARAMCD"), selected = "PARAMCD" ), param = choices_selected( choices = variable_choices(ADLB, "PARAM"), selected = "PARAM" ), timepoints = choices_selected( choices = variable_choices(ADLB, "ADY"), selected = "ADY" ), anrind = choices_selected( choices = variable_choices(ADLB, "ANRIND"), selected = "ANRIND" ), aval_var = choices_selected( choices = variable_choices(ADLB, "AVAL"), selected = "AVAL" ), avalu_var = choices_selected( choices = variable_choices(ADLB, "AVALU"), selected = "AVALU" ), decorators = list(table = rlisting_footer(.var_to_replace = "table")) ), # ------------------------------------------------------------------------- tm_t_pp_basic_info( label = "Basic Info", dataname = "ADSL", patient_col = "USUBJID", vars = choices_selected(choices = variable_choices(ADSL), selected = c("ARM", "AGE", "SEX", "COUNTRY", "RACE", "EOSSTT")) , decorators = list( table = rlisting_footer(.var_to_replace = "table") ) ), # ------------------------------------------------------------------------- tm_t_mult_events( label = "Concomitant Medications by Medication Class and Preferred Name", dataname = "ADCM", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), seq_var = choices_selected("CMSEQ", selected = "CMSEQ", fixed = TRUE), hlt = choices_selected( choices = variable_choices(ADCM, c("ATC1", "ATC2", "ATC3", "ATC4")), selected = c("ATC1", "ATC2", "ATC3", "ATC4") ), llt = choices_selected(choices = variable_choices(ADCM, c("CMDECOD")), selected = c("CMDECOD")), add_total = TRUE, event_type = "treatment", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_logistic( label = "Logistic Regression", dataname = "ADRS", arm_var = choices_selected( choices = variable_choices(ADRS, c("ARM", "ARMCD")), selected = "ARM" ), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(ADRS, "PARAMCD", "PARAM"), selected = "BESRSPI" ), cov_var = choices_selected( choices = c("SEX", "AGE", "BMRKR1", "BMRKR2"), selected = "SEX" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_exposure( label = "Duration of Exposure Table", dataname = "ADEX", paramcd = choices_selected( choices = value_choices(data[["ADEX"]], "PARAMCD", "PARAM"), selected = "TDURD" ), col_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("SEX", "ARM")), selected = "SEX" ), row_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("RACE", "REGION1", "STRATA1", "SEX")), selected = "RACE" ), parcat = choices_selected( choices = value_choices(data[["ADEX"]], "PARCAT2"), selected = "Drug A" ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events( label = "Adverse Event Table", 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", "AESOC")), selected = "AEBODSYS" ), add_total = TRUE, event_type = "adverse event", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events_patyear( label = "AE Rate Adjusted for Patient-Years At Risk Table", dataname = "ADAETTE", arm_var = choices_selected( choices = variable_choices(ADSL, c("ARM", "ARMCD")), selected = "ARMCD" ), add_total = TRUE, events_var = choices_selected( choices = variable_choices(ADAETTE, "n_events"), selected = "n_events", fixed = TRUE ), paramcd = choices_selected( choices = value_choices(ADAETTE, "PARAMCD", "PARAM"), selected = "AETTE1" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events_by_grade( label = "Adverse Events by Grade Table", 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", "AESOC")), selected = "AEBODSYS" ), grade = choices_selected( choices = variable_choices(ADAE, c("AETOXGR", "AESEV")), selected = "AETOXGR" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_coxreg( label = "Cox Reg.", dataname = "ADTTE", arm_var = choices_selected(c("ARM", "ARMCD", "ACTARMCD"), "ARM"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), strata_var = choices_selected( c("COUNTRY", "STRATA1", "STRATA2"), "STRATA1" ), cov_var = choices_selected( c("AGE", "BMRKR1", "BMRKR2", "REGION1"), "AGE" ), multivariate = TRUE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_abnormality( label = "Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), add_total = FALSE, by_vars = choices_selected( choices = variable_choices(ADLB, subset = c("LBCAT", "PARAM", "AVISIT")), selected = c("LBCAT", "PARAM"), keep_order = TRUE ), baseline_var = choices_selected( variable_choices(ADLB, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), grade = choices_selected( choices = variable_choices(ADLB, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), abnormal = list(low = "LOW", high = "HIGH"), exclude_base_abn = FALSE, decorators = list(insert_rrow_decorator("I am a good new row")) ), # ------------------------------------------------------------------------- tm_g_pp_vitals( label = "Vitals", dataname = "ADVS", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), paramcd = choices_selected( choices = variable_choices(ADVS, "PARAMCD"), selected = "PARAMCD" ), xaxis = choices_selected( choices = variable_choices(ADVS, "ADY"), selected = "ADY" ), aval_var = choices_selected( choices = variable_choices(ADVS, "AVAL"), selected = "AVAL" ), decorators = list(plot = add_title_decorator("plot")) ), # ------------------------------------------------------------------------- tm_g_pp_adverse_events( label = "Adverse Events", dataname = "ADAE", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), aeterm = choices_selected( choices = variable_choices(ADAE, "AETERM"), selected = "AETERM" ), tox_grade = choices_selected( choices = variable_choices(ADAE, "AETOXGR"), selected = "AETOXGR" ), causality = choices_selected( choices = variable_choices(ADAE, "AEREL"), selected = "AEREL" ), outcome = choices_selected( choices = variable_choices(ADAE, "AEOUT"), selected = "AEOUT" ), action = choices_selected( choices = variable_choices(ADAE, "AEACN"), selected = "AEACN" ), time = choices_selected( choices = variable_choices(ADAE, "ASTDY"), selected = "ASTDY" ), decod = NULL, decorators = list( plot = caption_decorator('I am a good caption', 'plot'), table = rlisting_footer(.var_to_replace = 'table') ) ), # ------------------------------------------------------------------------- tm_g_lineplot( label = "Line Plot", dataname = "ADLB", strata = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD", "ACTARMCD")), "ARM" ), y = choices_selected( variable_choices(ADLB, c("AVAL", "BASE", "CHG", "PCHG")), "AVAL" ), param = choices_selected( value_choices(ADLB, "PARAMCD", "PARAM"), "ALT" ), decorators = list(add_cowplot_title_decorator("plot")) ), # ------------------------------------------------------------------------- tm_g_km( label = "Kaplan-Meier Plot", dataname = "ADTTE", arm_var = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD", "ACTARMCD")), "ARM" ), paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), arm_ref_comp = arm_ref_comp, strata_var = choices_selected( variable_choices(ADSL, c("SEX", "BMRKR2")), "SEX" ), facet_var = choices_selected( variable_choices(ADSL, c("SEX", "BMRKR2")), NULL ), decorators = list(plot = add_cowplot_title_decorator(TRUE, "plot")) ), # ------------------------------------------------------------------------- tm_g_barchart_simple( label = "ADAE Analysis", x = data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = "ACTARM", multiple = FALSE ) ), fill = list( data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = "SEX", multiple = FALSE ) ), data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = NULL, multiple = FALSE ) ) ), x_facet = list( data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = "AETOXGR", multiple = FALSE ) ), data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = NULL, multiple = FALSE ) ) ), y_facet = list( data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = "AESEV", multiple = FALSE ) ), data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = NULL, multiple = FALSE ) ) ), decorators = list(plot = caption_decorator('The best', 'plot')) ) ) ) |> shiny::runApp() ``` </details> <details> <summary>Second App</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } # Preparation of the test case - use `EOSDY` and `DCSREAS` variables to demonstrate missing data. data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl |> mutate( DTHFL = case_when( !is.na(DTHDT) ~ "Y", TRUE ~ "" ) %>% with_label("Subject Death Flag") ) ADSL$EOSDY[1] <- NA_integer_ ADAE <- tmc_ex_adae .add_event_flags <- function(dat) { dat <- dat %>% mutate( TMPFL_SER = AESER == "Y", TMPFL_REL = AEREL == "Y", TMPFL_GR5 = AETOXGR == "5", TMP_SMQ01 = !is.na(SMQ01NAM), TMP_SMQ02 = !is.na(SMQ02NAM), TMP_CQ01 = !is.na(CQ01NAM) ) column_labels <- list( TMPFL_SER = "Serious AE", TMPFL_REL = "Related AE", TMPFL_GR5 = "Grade 5 AE", TMP_SMQ01 = aesi_label(dat[["SMQ01NAM"]], dat[["SMQ01SC"]]), TMP_SMQ02 = aesi_label("Y.9.9.9.9/Z.9.9.9.9 AESI"), TMP_CQ01 = aesi_label(dat[["CQ01NAM"]]) ) col_labels(dat)[names(column_labels)] <- as.character(column_labels) dat } #' Generating user-defined event flags. ADAE <- ADAE %>% .add_event_flags() .ae_anl_vars <- names(ADAE)[startsWith(names(ADAE), "TMPFL_")] .aesi_vars <- names(ADAE)[startsWith(names(ADAE), "TMP_")] ADTTE <- tmc_ex_adtte # responder ADRS <- tmc_ex_adrs %>% mutate( AVALC = d_onco_rsp_label(AVALC) %>% with_label("Character Result/Finding") ) %>% filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP") ADQS <- tmc_ex_adqs %>% filter(ABLFL != "Y" & ABLFL2 != "Y") %>% filter(AVISIT %in% c("WEEK 1 DAY 8", "WEEK 2 DAY 15", "WEEK 3 DAY 22")) %>% mutate( AVISIT = as.factor(AVISIT), AVISITN = rank(AVISITN) %>% as.factor() %>% as.numeric() %>% as.factor() #' making consecutive numeric factor ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADRS <- data[["ADRS"]] app <- init( data = data, modules = modules( # ------------------------------------------------------------------------- tm_a_mmrm( label = "MMRM", dataname = "ADQS", aval_var = choices_selected(c("AVAL", "CHG"), "AVAL"), id_var = choices_selected(c("USUBJID", "SUBJID"), "USUBJID"), arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), visit_var = choices_selected(c("AVISIT", "AVISITN"), "AVISIT"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(data[["ADQS"]], "PARAMCD", "PARAM"), selected = "FKSI-FWB" ), cov_var = choices_selected(c("BASE", "AGE", "SEX", "BASE:AVISIT"), NULL) , decorators = list( lsmeans_table = insert_rrow_decorator("A", .var_to_replace = "lsmeans_table") , lsmeans_plot = add_title_decorator("B", .var_to_replace = "lsmeans_plot") , covariance_table = insert_rrow_decorator("C", .var_to_replace = "covariance_table") , fixed_effects_table = insert_rrow_decorator("D", .var_to_replace = "fixed_effects_table") , diagnostic_table = insert_rrow_decorator(.var_to_replace = "diagnostic_table") , diagnostic_plot = add_title_decorator(.var_to_replace = "diagnostic_plot") ) ), # ------------------------------------------------------------------------- tm_t_binary_outcome( label = "Responders", dataname = "ADRS", paramcd = choices_selected( choices = value_choices(ADRS, "PARAMCD", "PARAM"), selected = "BESRSPI" ), arm_var = choices_selected( choices = variable_choices(ADRS, c("ARM", "ARMCD", "ACTARMCD")), selected = "ARM" ), arm_ref_comp = arm_ref_comp, strata_var = choices_selected( choices = variable_choices(ADRS, c("SEX", "BMRKR2", "RACE")), selected = "RACE" ), default_responses = list( BESRSPI = list( rsp = c("Complete Response (CR)", "Partial Response (PR)"), levels = c( "Complete Response (CR)", "Partial Response (PR)", "Stable Disease (SD)", "Progressive Disease (PD)" ) ), INVET = list( rsp = c("Stable Disease (SD)", "Not Evaluable (NE)"), levels = c( "Complete Response (CR)", "Not Evaluable (NE)", "Partial Response (PR)", "Progressive Disease (PD)", "Stable Disease (SD)" ) ), OVRINV = list( rsp = c("Progressive Disease (PD)", "Stable Disease (SD)"), levels = c("Progressive Disease (PD)", "Stable Disease (SD)", "Not Evaluable (NE)") ) ), decorators = list(insert_rrow_decorator("I am a new row")) ), # ------------------------------------------------------------------------- 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", data[[".ae_anl_vars"]]), selected = data[[".ae_anl_vars"]][1], keep_order = TRUE, fixed = FALSE ), flag_var_aesi = choices_selected( choices = variable_choices("ADAE", data[[".aesi_vars"]]), selected = data[[".aesi_vars"]][1], keep_order = TRUE, fixed = FALSE ), add_total = TRUE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_summary( label = "Demographic Table", dataname = "ADSL", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), add_total = TRUE, summarize_vars = choices_selected( c("SEX", "RACE", "BMRKR2", "EOSDY", "DCSREAS", "AGE"), c("SEX", "RACE") ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details>
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 17, 2024
# Pull Request <!--- Replace `#nnn` with your issue link for reference. --> Part of insightsengineering/teal#1371 (comment) ### Changes description - Tracks changes in the template code of the decorators feature branch - Renames variables to be `plot`, `table` or (in case of multiple decoratable elements) `<name>_plot` and `<name>_table` ### Workflow Manually triggered: https://github.com/insightsengineering/teal.modules.clinical/actions/runs/12359120026 [![Check 🛠](https://github.com/insightsengineering/teal.modules.clinical/actions/workflows/check.yaml/badge.svg?branch=snapshots%401187_decorate_output%40main)](https://github.com/insightsengineering/teal.modules.clinical/actions/workflows/check.yaml)
averissimo
added a commit
to insightsengineering/teal.modules.clinical
that referenced
this issue
Dec 17, 2024
- Partner to insightsengineering/teal#1357 - Introduces decorators to modules. More about decorators in here insightsengineering/teal#1384 - Part 1 of insightsengineering/teal#1371 (comment) ### Changes description - Adds internal wrapper around `srv_decorate_data` as utility to append code after decorator _(such as `print(plot)`)_ - Implements decorators in modules #### Checklist for final review: Double check check for every module: - Works with and without decorators - Has param and section in documentation - Code shows in "Show R code" - Reporter shows both the outputs and code #### Todo on feature branch - [x] Link the `teal_transform_module` parameter to an extended explanation as [suggested here](https://github.com/insightsengineering/teal.modules.clinical/pull/1252/files/a78c0baa0996fb30fdff551bccb7bab0ec86caa6#r1870909229) - [x] Meet with SME to validate some changes in template, topics: - modules with listing/dt - Merge all modules - [x] Part 1 of insightsengineering/teal#1371 (comment) - [x] Part 2 of insightsengineering/teal#1371 (comment) - [x] Accept changes to snapshots in regression testing #1304 #### Example apps Not all modules could be used in same App as the examples' data are not 100% compatible. Hence the 2 apps below. <details> <summary>Example app</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Decorators ------------------------------------------------------------------ insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New rtables row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } add_title_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Title", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Add title?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::ggtitle("Title added by decorator") }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } caption_decorator <- function(default_caption = "I am a good decorator", .var_to_replace = "plot") { teal_transform_module( label = "Caption", ui = function(id) shiny::textInput(shiny::NS(id, "footnote"), "Footnote", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- .var_to_replace + ggplot2::labs(caption = footnote) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } change_theme_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Theme", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Apply dark theme?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::theme_dark() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } add_cowplot_title_decorator <- function(default_check = TRUE, .var_to_replace = "plot") { teal_transform_module( label = "Cowplot title", ui = function(id) shiny::checkboxInput(NS(id, "flag"), "Add title?", TRUE), server = make_teal_transform_server( substitute({ if (flag) .var_to_replace <- .var_to_replace + ggplot2::ggtitle("Title added by decorator") + cowplot::theme_cowplot() }, env = list(.var_to_replace = as.name(.var_to_replace)) ) ) ) } rlisting_footer <- function(default_footer = "I am a good footer", .var_to_replace = "table_listing") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "footer"), "footer", value = default_footer), server = make_teal_transform_server( substitute({ rlistings::main_footer(.var_to_replace) <- footer }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } # End of decorators ----------------------------------------------------------- library(dplyr) # arm_ref_comp <- list(ARMCD = list(ref = "ARM B", comp = c("ARM A", "ARM C"))) arm_ref_comp <- list( ACTARMCD = list(ref = "ARM B", comp = c("ARM A", "ARM C")), ARM = list(ref = "B: Placebo", comp = c("A: Drug X", "C: Combination")) ) data <- within(teal_data(), { ADSL <- tmc_ex_adsl |> mutate(ITTFL = factor("Y") |> with_label("Intent-To-Treat Population Flag")) |> mutate(DTHFL = case_when(!is.na(DTHDT) ~ "Y", TRUE ~ "") |> with_label("Subject Death Flag")) ADAE <- tmc_ex_adae |> filter(!((AETOXGR == 1) & (AESEV == "MILD") & (ARM == "A: Drug X"))) ADAE$ASTDY <- structure( as.double(ADAE$ASTDY, unit = attr(ADAE$ASTDY, "units", exact = TRUE)), label = attr(ADAE$ASTDY, "label", exact = TRUE) ) .lbls_adae <- col_labels(tmc_ex_adae) ADAE <- tmc_ex_adae %>% mutate_if(is.character, as.factor) #' be certain of having factors col_labels(ADAE) <- .lbls_adae ADTTE <- tmc_ex_adtte ADLB <- tmc_ex_adlb |> mutate(AVISIT == forcats::fct_reorder(AVISIT, AVISITN, min)) |> mutate( ONTRTFL = case_when( AVISIT %in% c("SCREENING", "BASELINE") ~ "", TRUE ~ "Y" ) |> with_label("On Treatment Record Flag") ) ADVS <- tmc_ex_advs ADRS <- tmc_ex_adrs |> mutate( AVALC = d_onco_rsp_label(AVALC) |> with_label("Character Result/Finding") ) |> filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP") |> filter(PARAMCD %in% c("BESRSPI", "INVET")) ADAETTE <- tmc_ex_adaette %>% filter(PARAMCD %in% c("AETTE1", "AETTE2", "AETTE3")) %>% mutate(is_event = CNSR == 0) %>% mutate(n_events = as.integer(is_event)) .add_event_flags <- function(dat) { dat <- dat %>% mutate( TMPFL_SER = AESER == "Y", TMPFL_REL = AEREL == "Y", TMPFL_GR5 = AETOXGR == "5", TMP_SMQ01 = !is.na(SMQ01NAM), TMP_SMQ02 = !is.na(SMQ02NAM), TMP_CQ01 = !is.na(CQ01NAM) ) column_labels <- list( TMPFL_SER = "Serious AE", TMPFL_REL = "Related AE", TMPFL_GR5 = "Grade 5 AE", TMP_SMQ01 = aesi_label(dat[["SMQ01NAM"]], dat[["SMQ01SC"]]), TMP_SMQ02 = aesi_label("Y.9.9.9.9/Z.9.9.9.9 AESI"), TMP_CQ01 = aesi_label(dat[["CQ01NAM"]]) ) col_labels(dat)[names(column_labels)] <- as.character(column_labels) dat } ADEX <- tmc_ex_adex set.seed(1, kind = "Mersenne-Twister") .labels <- col_labels(ADEX, fill = FALSE) ADEX <- ADEX %>% distinct(USUBJID, .keep_all = TRUE) %>% mutate( PARAMCD = "TDURD", PARAM = "Overall duration (days)", AVAL = sample(x = seq(1, 200), size = n(), replace = TRUE), AVALU = "Days" ) %>% bind_rows(ADEX) col_labels(ADEX) <- .labels ADCM <- tmc_ex_adcm ADMH <- tmc_ex_admh ADCM$CMASTDTM <- ADCM$ASTDTM ADCM$CMAENDTM <- ADCM$AENDTM ADEG <- tmc_ex_adeg # smq .names_baskets <- grep("^(SMQ|CQ).*NAM$", names(ADAE), value = TRUE) .names_scopes <- grep("^SMQ.*SC$", names(ADAE), value = TRUE) .cs_baskets <- choices_selected( choices = variable_choices(ADAE, subset = .names_baskets), selected = .names_baskets ) .cs_scopes <- choices_selected( choices = variable_choices(ADAE, subset = .names_scopes), selected = .names_scopes, fixed = TRUE ) # summary ADSL$EOSDY[1] <- NA_integer_ }) join_keys(data) <- default_cdisc_join_keys[names(data)] adcm_keys <- c("STUDYID", "USUBJID", "ASTDTM", "CMSEQ", "ATC1", "ATC2", "ATC3", "ATC4") join_keys(data)["ADCM", "ADCM"] <- adcm_keys # Use in choices selected ----------------------------------------------------- ADSL <- data[["ADSL"]] ADQS <- data[["ADQS"]] ADAE <- data[["ADAE"]] ADTTE <- data[["ADTTE"]] ADLB <- data[["ADLB"]] ADAE <- data[["ADAE"]] ADVS <- data[["ADVS"]] ADRS <- data[["ADRS"]] ADAETTE <- data[["ADAETTE"]] ADEX <- data[["ADEX"]] ADCM <- data[["ADCM"]] ADMH <- data[["ADMH"]] ADEG <- data[["ADEG"]] # Init ------------------------------------------------------------------------ init( data = data, modules = modules( # ------------------------------------------------------------------------- tm_t_summary_by( label = "Summary by Row Groups Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, c("ARM", "ARMCD")), selected = "ARM" ), add_total = TRUE, by_vars = choices_selected( choices = variable_choices(ADLB, c("PARAM", "AVISIT")), selected = c("AVISIT") ), summarize_vars = choices_selected( choices = variable_choices(ADLB, c("AVAL", "CHG")), selected = c("AVAL") ), useNA = "ifany", paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_smq( label = "Adverse Events by SMQ Table", dataname = "ADAE", arm_var = choices_selected( choices = variable_choices(data[["ADSL"]], subset = c("ARM", "SEX")), selected = "ARM" ), add_total = FALSE, baskets = data[[".cs_baskets"]], scopes = data[[".cs_scopes"]], llt = choices_selected( choices = variable_choices(data[["ADAE"]], subset = c("AEDECOD")), selected = "AEDECOD" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_grade( label = "Grade Laboratory Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( choices = value_choices(ADLB, "PARAMCD", "PARAM"), selected = "ALT" ), worst_flag_var = choices_selected( choices = variable_choices(ADLB, subset = c("WGRLOVFL", "WGRLOFL", "WGRHIVFL", "WGRHIFL")), selected = c("WGRLOVFL") ), worst_flag_indicator = choices_selected( value_choices(ADLB, "WGRLOVFL"), selected = "Y", fixed = TRUE ), anl_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("ATOXGR")), selected = c("ATOXGR"), fixed = TRUE ), base_toxgrade_var = choices_selected( choices = variable_choices(ADLB, subset = c("BTOXGR")), selected = c("BTOXGR"), fixed = TRUE ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_arm( label = "Shift by Arm Table", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "HR" ), visit_var = choices_selected( value_choices(ADEG, "AVISIT"), selected = "POST-BASELINE MINIMUM" ), aval_var = choices_selected( variable_choices(ADEG, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), baseline_var = choices_selected( variable_choices(ADEG, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_shift_by_arm_by_worst( label = "Shift by Arm Table (by worst)", dataname = "ADEG", arm_var = choices_selected( variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), paramcd = choices_selected( value_choices(ADEG, "PARAMCD"), selected = "ECGINTP" ), worst_flag_var = choices_selected( variable_choices(ADEG, c("WORS02FL", "WORS01FL")), selected = "WORS02FL" ), worst_flag = choices_selected( value_choices(ADEG, "WORS02FL"), selected = "Y", fixed = TRUE ), aval_var = choices_selected( variable_choices(ADEG, c("AVALC", "ANRIND")), selected = "AVALC" ), baseline_var = choices_selected( variable_choices(ADEG, c("BASEC", "BNRIND")), selected = "BASEC" ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_pp_prior_medication( label = "Prior Medication", dataname = "ADCM", parentname = "ADSL", patient_col = "USUBJID", atirel = choices_selected( choices = variable_choices(ADCM, "ATIREL"), selected = "ATIREL" ), cmdecod = choices_selected( choices = variable_choices(ADCM, "CMDECOD"), selected = "CMDECOD" ), cmindc = choices_selected( choices = variable_choices(ADCM, "CMINDC"), selected = "CMINDC" ), cmstdy = choices_selected( choices = variable_choices(ADCM, "ASTDY"), selected = "ASTDY" ), decorators = list( table = rlisting_footer(.var_to_replace = "table") ) ), # ------------------------------------------------------------------------- tm_t_pp_medical_history( label = "Medical History", dataname = "ADMH", parentname = "ADSL", patient_col = "USUBJID", mhterm = choices_selected( choices = variable_choices(ADMH, c("MHTERM")), selected = "MHTERM" ), mhbodsys = choices_selected( choices = variable_choices(ADMH, "MHBODSYS"), selected = "MHBODSYS" ), mhdistat = choices_selected( choices = variable_choices(ADMH, "MHDISTAT"), selected = "MHDISTAT" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_pp_laboratory( label = "Vitals", dataname = "ADLB", patient_col = "USUBJID", paramcd = choices_selected( choices = variable_choices(ADLB, "PARAMCD"), selected = "PARAMCD" ), param = choices_selected( choices = variable_choices(ADLB, "PARAM"), selected = "PARAM" ), timepoints = choices_selected( choices = variable_choices(ADLB, "ADY"), selected = "ADY" ), anrind = choices_selected( choices = variable_choices(ADLB, "ANRIND"), selected = "ANRIND" ), aval_var = choices_selected( choices = variable_choices(ADLB, "AVAL"), selected = "AVAL" ), avalu_var = choices_selected( choices = variable_choices(ADLB, "AVALU"), selected = "AVALU" ), decorators = list(table = rlisting_footer(.var_to_replace = "table")) ), # ------------------------------------------------------------------------- tm_t_pp_basic_info( label = "Basic Info", dataname = "ADSL", patient_col = "USUBJID", vars = choices_selected(choices = variable_choices(ADSL), selected = c("ARM", "AGE", "SEX", "COUNTRY", "RACE", "EOSSTT")) , decorators = list( table = rlisting_footer(.var_to_replace = "table") ) ), # ------------------------------------------------------------------------- tm_t_mult_events( label = "Concomitant Medications by Medication Class and Preferred Name", dataname = "ADCM", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), seq_var = choices_selected("CMSEQ", selected = "CMSEQ", fixed = TRUE), hlt = choices_selected( choices = variable_choices(ADCM, c("ATC1", "ATC2", "ATC3", "ATC4")), selected = c("ATC1", "ATC2", "ATC3", "ATC4") ), llt = choices_selected(choices = variable_choices(ADCM, c("CMDECOD")), selected = c("CMDECOD")), add_total = TRUE, event_type = "treatment", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_logistic( label = "Logistic Regression", dataname = "ADRS", arm_var = choices_selected( choices = variable_choices(ADRS, c("ARM", "ARMCD")), selected = "ARM" ), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(ADRS, "PARAMCD", "PARAM"), selected = "BESRSPI" ), cov_var = choices_selected( choices = c("SEX", "AGE", "BMRKR1", "BMRKR2"), selected = "SEX" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_exposure( label = "Duration of Exposure Table", dataname = "ADEX", paramcd = choices_selected( choices = value_choices(data[["ADEX"]], "PARAMCD", "PARAM"), selected = "TDURD" ), col_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("SEX", "ARM")), selected = "SEX" ), row_by_var = choices_selected( choices = variable_choices(data[["ADEX"]], subset = c("RACE", "REGION1", "STRATA1", "SEX")), selected = "RACE" ), parcat = choices_selected( choices = value_choices(data[["ADEX"]], "PARCAT2"), selected = "Drug A" ), add_total = FALSE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events( label = "Adverse Event Table", 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", "AESOC")), selected = "AEBODSYS" ), add_total = TRUE, event_type = "adverse event", decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events_patyear( label = "AE Rate Adjusted for Patient-Years At Risk Table", dataname = "ADAETTE", arm_var = choices_selected( choices = variable_choices(ADSL, c("ARM", "ARMCD")), selected = "ARMCD" ), add_total = TRUE, events_var = choices_selected( choices = variable_choices(ADAETTE, "n_events"), selected = "n_events", fixed = TRUE ), paramcd = choices_selected( choices = value_choices(ADAETTE, "PARAMCD", "PARAM"), selected = "AETTE1" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_events_by_grade( label = "Adverse Events by Grade Table", 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", "AESOC")), selected = "AEBODSYS" ), grade = choices_selected( choices = variable_choices(ADAE, c("AETOXGR", "AESEV")), selected = "AETOXGR" ), decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_coxreg( label = "Cox Reg.", dataname = "ADTTE", arm_var = choices_selected(c("ARM", "ARMCD", "ACTARMCD"), "ARM"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), strata_var = choices_selected( c("COUNTRY", "STRATA1", "STRATA2"), "STRATA1" ), cov_var = choices_selected( c("AGE", "BMRKR1", "BMRKR2", "REGION1"), "AGE" ), multivariate = TRUE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_abnormality( label = "Abnormality Table", dataname = "ADLB", arm_var = choices_selected( choices = variable_choices(ADSL, subset = c("ARM", "ARMCD")), selected = "ARM" ), add_total = FALSE, by_vars = choices_selected( choices = variable_choices(ADLB, subset = c("LBCAT", "PARAM", "AVISIT")), selected = c("LBCAT", "PARAM"), keep_order = TRUE ), baseline_var = choices_selected( variable_choices(ADLB, subset = "BNRIND"), selected = "BNRIND", fixed = TRUE ), grade = choices_selected( choices = variable_choices(ADLB, subset = "ANRIND"), selected = "ANRIND", fixed = TRUE ), abnormal = list(low = "LOW", high = "HIGH"), exclude_base_abn = FALSE, decorators = list(insert_rrow_decorator("I am a good new row")) ), # ------------------------------------------------------------------------- tm_g_pp_vitals( label = "Vitals", dataname = "ADVS", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), paramcd = choices_selected( choices = variable_choices(ADVS, "PARAMCD"), selected = "PARAMCD" ), xaxis = choices_selected( choices = variable_choices(ADVS, "ADY"), selected = "ADY" ), aval_var = choices_selected( choices = variable_choices(ADVS, "AVAL"), selected = "AVAL" ), decorators = list(plot = add_title_decorator("plot")) ), # ------------------------------------------------------------------------- tm_g_pp_adverse_events( label = "Adverse Events", dataname = "ADAE", parentname = "ADSL", patient_col = "USUBJID", plot_height = c(600L, 200L, 2000L), aeterm = choices_selected( choices = variable_choices(ADAE, "AETERM"), selected = "AETERM" ), tox_grade = choices_selected( choices = variable_choices(ADAE, "AETOXGR"), selected = "AETOXGR" ), causality = choices_selected( choices = variable_choices(ADAE, "AEREL"), selected = "AEREL" ), outcome = choices_selected( choices = variable_choices(ADAE, "AEOUT"), selected = "AEOUT" ), action = choices_selected( choices = variable_choices(ADAE, "AEACN"), selected = "AEACN" ), time = choices_selected( choices = variable_choices(ADAE, "ASTDY"), selected = "ASTDY" ), decod = NULL, decorators = list( plot = caption_decorator('I am a good caption', 'plot'), table = rlisting_footer(.var_to_replace = 'table') ) ), # ------------------------------------------------------------------------- tm_g_lineplot( label = "Line Plot", dataname = "ADLB", strata = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD", "ACTARMCD")), "ARM" ), y = choices_selected( variable_choices(ADLB, c("AVAL", "BASE", "CHG", "PCHG")), "AVAL" ), param = choices_selected( value_choices(ADLB, "PARAMCD", "PARAM"), "ALT" ), decorators = list(add_cowplot_title_decorator("plot")) ), # ------------------------------------------------------------------------- tm_g_km( label = "Kaplan-Meier Plot", dataname = "ADTTE", arm_var = choices_selected( variable_choices(ADSL, c("ARM", "ARMCD", "ACTARMCD")), "ARM" ), paramcd = choices_selected( value_choices(ADTTE, "PARAMCD", "PARAM"), "OS" ), arm_ref_comp = arm_ref_comp, strata_var = choices_selected( variable_choices(ADSL, c("SEX", "BMRKR2")), "SEX" ), facet_var = choices_selected( variable_choices(ADSL, c("SEX", "BMRKR2")), NULL ), decorators = list(plot = add_cowplot_title_decorator(TRUE, "plot")) ), # ------------------------------------------------------------------------- tm_g_barchart_simple( label = "ADAE Analysis", x = data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = "ACTARM", multiple = FALSE ) ), fill = list( data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = "SEX", multiple = FALSE ) ), data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = NULL, multiple = FALSE ) ) ), x_facet = list( data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = "AETOXGR", multiple = FALSE ) ), data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = NULL, multiple = FALSE ) ) ), y_facet = list( data_extract_spec( dataname = "ADAE", select = select_spec( choices = variable_choices(ADAE, c("AETOXGR", "AESEV", "AESER")), selected = "AESEV", multiple = FALSE ) ), data_extract_spec( dataname = "ADSL", select = select_spec( choices = variable_choices( ADSL, c( "ARM", "ACTARM", "SEX", "RACE", "ITTFL", "SAFFL", "STRATA2" ) ), selected = NULL, multiple = FALSE ) ) ), decorators = list(plot = caption_decorator('The best', 'plot')) ) ) ) |> shiny::runApp() ``` </details> <details> <summary>Second App</summary> ```r # Load packages pkgload::load_all("../teal.modules.clinical", export_all = FALSE) # Example below insert_rrow_decorator <- function(default_caption = "I am a good new row", .var_to_replace = "table") { teal_transform_module( label = "New row", ui = function(id) shiny::textInput(shiny::NS(id, "new_row"), "New row", value = default_caption), server = make_teal_transform_server( substitute({ .var_to_replace <- rtables::insert_rrow(.var_to_replace, rtables::rrow(new_row)) }, env = list(.var_to_replace = as.name(.var_to_replace))) ) ) } # Preparation of the test case - use `EOSDY` and `DCSREAS` variables to demonstrate missing data. data <- teal_data() data <- within(data, { ADSL <- tmc_ex_adsl |> mutate( DTHFL = case_when( !is.na(DTHDT) ~ "Y", TRUE ~ "" ) %>% with_label("Subject Death Flag") ) ADSL$EOSDY[1] <- NA_integer_ ADAE <- tmc_ex_adae .add_event_flags <- function(dat) { dat <- dat %>% mutate( TMPFL_SER = AESER == "Y", TMPFL_REL = AEREL == "Y", TMPFL_GR5 = AETOXGR == "5", TMP_SMQ01 = !is.na(SMQ01NAM), TMP_SMQ02 = !is.na(SMQ02NAM), TMP_CQ01 = !is.na(CQ01NAM) ) column_labels <- list( TMPFL_SER = "Serious AE", TMPFL_REL = "Related AE", TMPFL_GR5 = "Grade 5 AE", TMP_SMQ01 = aesi_label(dat[["SMQ01NAM"]], dat[["SMQ01SC"]]), TMP_SMQ02 = aesi_label("Y.9.9.9.9/Z.9.9.9.9 AESI"), TMP_CQ01 = aesi_label(dat[["CQ01NAM"]]) ) col_labels(dat)[names(column_labels)] <- as.character(column_labels) dat } #' Generating user-defined event flags. ADAE <- ADAE %>% .add_event_flags() .ae_anl_vars <- names(ADAE)[startsWith(names(ADAE), "TMPFL_")] .aesi_vars <- names(ADAE)[startsWith(names(ADAE), "TMP_")] ADTTE <- tmc_ex_adtte # responder ADRS <- tmc_ex_adrs %>% mutate( AVALC = d_onco_rsp_label(AVALC) %>% with_label("Character Result/Finding") ) %>% filter(PARAMCD != "OVRINV" | AVISIT == "FOLLOW UP") ADQS <- tmc_ex_adqs %>% filter(ABLFL != "Y" & ABLFL2 != "Y") %>% filter(AVISIT %in% c("WEEK 1 DAY 8", "WEEK 2 DAY 15", "WEEK 3 DAY 22")) %>% mutate( AVISIT = as.factor(AVISIT), AVISITN = rank(AVISITN) %>% as.factor() %>% as.numeric() %>% as.factor() #' making consecutive numeric factor ) }) join_keys(data) <- default_cdisc_join_keys[names(data)] ADSL <- data[["ADSL"]] ADRS <- data[["ADRS"]] app <- init( data = data, modules = modules( # ------------------------------------------------------------------------- tm_a_mmrm( label = "MMRM", dataname = "ADQS", aval_var = choices_selected(c("AVAL", "CHG"), "AVAL"), id_var = choices_selected(c("USUBJID", "SUBJID"), "USUBJID"), arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), visit_var = choices_selected(c("AVISIT", "AVISITN"), "AVISIT"), arm_ref_comp = arm_ref_comp, paramcd = choices_selected( choices = value_choices(data[["ADQS"]], "PARAMCD", "PARAM"), selected = "FKSI-FWB" ), cov_var = choices_selected(c("BASE", "AGE", "SEX", "BASE:AVISIT"), NULL) , decorators = list( lsmeans_table = insert_rrow_decorator("A", .var_to_replace = "lsmeans_table") , lsmeans_plot = add_title_decorator("B", .var_to_replace = "lsmeans_plot") , covariance_table = insert_rrow_decorator("C", .var_to_replace = "covariance_table") , fixed_effects_table = insert_rrow_decorator("D", .var_to_replace = "fixed_effects_table") , diagnostic_table = insert_rrow_decorator(.var_to_replace = "diagnostic_table") , diagnostic_plot = add_title_decorator(.var_to_replace = "diagnostic_plot") ) ), # ------------------------------------------------------------------------- tm_t_binary_outcome( label = "Responders", dataname = "ADRS", paramcd = choices_selected( choices = value_choices(ADRS, "PARAMCD", "PARAM"), selected = "BESRSPI" ), arm_var = choices_selected( choices = variable_choices(ADRS, c("ARM", "ARMCD", "ACTARMCD")), selected = "ARM" ), arm_ref_comp = arm_ref_comp, strata_var = choices_selected( choices = variable_choices(ADRS, c("SEX", "BMRKR2", "RACE")), selected = "RACE" ), default_responses = list( BESRSPI = list( rsp = c("Complete Response (CR)", "Partial Response (PR)"), levels = c( "Complete Response (CR)", "Partial Response (PR)", "Stable Disease (SD)", "Progressive Disease (PD)" ) ), INVET = list( rsp = c("Stable Disease (SD)", "Not Evaluable (NE)"), levels = c( "Complete Response (CR)", "Not Evaluable (NE)", "Partial Response (PR)", "Progressive Disease (PD)", "Stable Disease (SD)" ) ), OVRINV = list( rsp = c("Progressive Disease (PD)", "Stable Disease (SD)"), levels = c("Progressive Disease (PD)", "Stable Disease (SD)", "Not Evaluable (NE)") ) ), decorators = list(insert_rrow_decorator("I am a new row")) ), # ------------------------------------------------------------------------- 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", data[[".ae_anl_vars"]]), selected = data[[".ae_anl_vars"]][1], keep_order = TRUE, fixed = FALSE ), flag_var_aesi = choices_selected( choices = variable_choices("ADAE", data[[".aesi_vars"]]), selected = data[[".aesi_vars"]][1], keep_order = TRUE, fixed = FALSE ), add_total = TRUE, decorators = list(insert_rrow_decorator()) ), # ------------------------------------------------------------------------- tm_t_summary( label = "Demographic Table", dataname = "ADSL", arm_var = choices_selected(c("ARM", "ARMCD"), "ARM"), add_total = TRUE, summarize_vars = choices_selected( c("SEX", "RACE", "BMRKR2", "EOSDY", "DCSREAS", "AGE"), c("SEX", "RACE") ), useNA = "ifany", decorators = list(insert_rrow_decorator()) ) ) ) |> shiny::runApp() ``` </details> --------- Signed-off-by: Marcin <[email protected]> Signed-off-by: Lluís Revilla <[email protected]> Signed-off-by: André Veríssimo <[email protected]> Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Marcin <[email protected]> Co-authored-by: m7pr <[email protected]> Co-authored-by: Lluís Revilla <[email protected]> Co-authored-by: Lluís Revilla <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Blocked by #1368
table
,listing
,graph
Items:
Part 1
tm_a_gee
teal.modules.clinical#1262tm_g_ci
teal.modules.clinical#1265tm_g_forest_rsp
teal.modules.clinical#1266tm_g_forest_tte
teal.modules.clinical#1264tm_g_ipp
teal.modules.clinical#1263tm_g_km
teal.modules.clinical#1254tm_g_lineplot
teal.modules.clinical#1255tm_g_pp_patient_timeline
teal.modules.clinical#1270tm_g_pp_therapy
teal.modules.clinical#1268tm_g_pp_vitals
teal.modules.clinical#1261tm_t_abnormality
teal.modules.clinical#1257tm_t_abnormality_by_worst_grade
teal.modules.clinical#1260tm_t_ancova
teal.modules.clinical#1256tm_g_barchart_simple
teal.modules.clinical#1267tm_g_pp_adverse_events
teal.modules.clinical#1269Moved from part 2 to part 1
tm_t_binary_outcome
teal.modules.clinical#1273tm_t_coxreg
teal.modules.clinical#1274tm_t_events
teal.modules.clinical#1275tm_t events by grade
teal.modules.clinical#1276tm_t_events_patyear
teal.modules.clinical#1277tm_t_events_summary
teal.modules.clinical#1278tm_t_exposure
teal.modules.clinical#1279tm_t_tte
teal.modules.clinical#1280tm t mult events
teal.modules.clinical#1281tm_t_pp_basic_info
teal.modules.clinical#1282Part 2
tm_t_logistic
teal.modules.clinical#1290tm_t_pp_laboratory
teal.modules.clinical#1291tm_t_pp_medical_history
teal.modules.clinical#1289tm_t_pp_prior_medication
teal.modules.clinical#1288tm_t_shift_by_arm
teal.modules.clinical#1287tm_t_shift_by_arm_by_worst
teal.modules.clinical#1286tm_t_shift_by_grade
teal.modules.clinical#1285tm_t_smq
teal.modules.clinical#1292tm_t_summary
teal.modules.clinical#1293tm_t_summary_by
teal.modules.clinical#1294Moved from part 1
tm_a_mmrm
teal.modules.clinical#1300The text was updated successfully, but these errors were encountered: