Skip to content

Commit 824efcf

Browse files
m7prdependabot-preview[bot]averissimo
authored
introduce decorators for tm_t_crosstable (#806)
Part of https://github.com/insightsengineering/teal/issues/1370 <details><summary> Working Example </summary> ````r devtools::load_all("../teal") devtools::load_all(".") split_by_decorator <- teal_transform_module( label = "Footnote", ui = function(id) shiny::textInput( shiny::NS(id, "text"), "Insert row", "Hello World!" ), server = function(id, data) { moduleServer(id, function(input, output, session) { logger::log_info("🟢 Text called to action!", namespace = "teal.modules.general") reactive( within( data(), { table <- table %>% insert_rrow(rrow(text)) }, text = input$text ) ) }) } ) # CDISC data example data <- teal_data() data <- within(data, { ADSL <- rADSL }) join_keys(data) <- default_cdisc_join_keys[names(data)] app <- init( data = data, modules = modules( tm_t_crosstable( label = "Cross Table", x = data_extract_spec( dataname = "ADSL", select = select_spec( label = "Select variable:", choices = variable_choices(data[["ADSL"]], subset = function(data) { idx <- !vapply(data, inherits, logical(1), c("Date", "POSIXct", "POSIXlt")) return(names(data)[idx]) }), selected = "COUNTRY", multiple = TRUE, ordered = TRUE, fixed = FALSE ) ), y = data_extract_spec( dataname = "ADSL", select = select_spec( label = "Select variable:", choices = variable_choices(data[["ADSL"]], subset = function(data) { idx <- vapply(data, is.factor, logical(1)) return(names(data)[idx]) }), selected = "SEX", multiple = FALSE, fixed = FALSE ) ), decorators = list(split_by_decorator) ) ) ) if (interactive()) { shinyApp(app$ui, app$server) } ```` </details> --------- Signed-off-by: Marcin <[email protected]> Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: André Veríssimo <[email protected]>
1 parent 7deda6d commit 824efcf

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

R/tm_t_crosstable.R

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525
#'
2626
#' @inherit shared_params return
2727
#'
28+
#' @section Decorating `tm_t_crosstable`:
29+
#'
30+
#' This module generates the following objects, which can be modified in place using decorators:
31+
#' - `table` (`ElementaryTable` - output of `rtables::build_table`)
32+
#'
33+
#' For additional details and examples of decorators, refer to the vignette
34+
#' `vignette("decorate-modules-output", package = "teal")` or the [`teal_transform_module()`] documentation.
35+
#'
2836
#' @examplesShinylive
2937
#' library(teal.modules.general)
3038
#' interactive <- function() TRUE
@@ -134,7 +142,8 @@ tm_t_crosstable <- function(label = "Cross Table",
134142
show_total = TRUE,
135143
pre_output = NULL,
136144
post_output = NULL,
137-
basic_table_args = teal.widgets::basic_table_args()) {
145+
basic_table_args = teal.widgets::basic_table_args(),
146+
decorators = NULL) {
138147
message("Initializing tm_t_crosstable")
139148

140149
# Requires Suggested packages
@@ -158,6 +167,7 @@ tm_t_crosstable <- function(label = "Cross Table",
158167
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
159168
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
160169
checkmate::assert_class(basic_table_args, classes = "basic_table_args")
170+
checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)
161171
# End of assertions
162172

163173
# Make UI args
@@ -167,7 +177,8 @@ tm_t_crosstable <- function(label = "Cross Table",
167177
label = label,
168178
x = x,
169179
y = y,
170-
basic_table_args = basic_table_args
180+
basic_table_args = basic_table_args,
181+
decorators = decorators
171182
)
172183

173184
ans <- module(
@@ -184,6 +195,7 @@ tm_t_crosstable <- function(label = "Cross Table",
184195

185196
# UI function for the cross-table module
186197
ui_t_crosstable <- function(id, x, y, show_percentage, show_total, pre_output, post_output, ...) {
198+
args <- list(...)
187199
ns <- NS(id)
188200
is_single_dataset <- teal.transform::is_single_dataset(x, y)
189201

@@ -221,7 +233,8 @@ ui_t_crosstable <- function(id, x, y, show_percentage, show_total, pre_output, p
221233
checkboxInput(ns("show_percentage"), "Show column percentage", value = show_percentage),
222234
checkboxInput(ns("show_total"), "Show total column", value = show_total)
223235
)
224-
)
236+
),
237+
ui_teal_transform_data(ns("decorate"), transformators = args$decorators)
225238
),
226239
forms = tagList(
227240
teal.widgets::verbatim_popup_ui(ns("rcode"), "Show R code")
@@ -232,7 +245,7 @@ ui_t_crosstable <- function(id, x, y, show_percentage, show_total, pre_output, p
232245
}
233246

234247
# Server function for the cross-table module
235-
srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y, basic_table_args) {
248+
srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y, basic_table_args, decorators) {
236249
with_reporter <- !missing(reporter) && inherits(reporter, "Reporter")
237250
with_filter <- !missing(filter_panel_api) && inherits(filter_panel_api, "FilterPanelAPI")
238251
checkmate::assert_class(data, "reactive")
@@ -351,7 +364,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
351364
teal.code::eval_code(
352365
substitute(
353366
expr = {
354-
lyt <- basic_tables %>%
367+
table <- basic_tables %>%
355368
split_call %>% # styler: off
356369
rtables::add_colcounts() %>%
357370
tern::analyze_vars(
@@ -387,19 +400,22 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
387400
substitute(
388401
expr = {
389402
ANL <- tern::df_explicit_na(ANL)
390-
tbl <- rtables::build_table(lyt = lyt, df = ANL[order(ANL[[y_name]]), ])
391-
tbl
403+
table <- rtables::build_table(lyt = table, df = ANL[order(ANL[[y_name]]), ])
392404
},
393405
env = list(y_name = y_name)
394406
)
395407
)
396408
})
397409

410+
decorated_output_q_no_print <- srv_teal_transform_data("decorate", data = output_q, transformators = decorators)
411+
decorated_output_q <- reactive(within(decorated_output_q_no_print(), expr = table))
412+
398413
output$title <- renderText(output_q()[["title"]])
399414

400415
table_r <- reactive({
401416
req(iv_r()$is_valid())
402-
output_q()[["tbl"]]
417+
req(output_q())
418+
decorated_output_q()[["table"]]
403419
})
404420

405421
teal.widgets::table_with_settings_srv(
@@ -409,7 +425,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
409425

410426
teal.widgets::verbatim_popup_srv(
411427
id = "rcode",
412-
verbatim_content = reactive(teal.code::get_code(output_q())),
428+
verbatim_content = reactive(teal.code::get_code(req(decorated_output_q()))),
413429
title = "Show R Code for Cross-Table"
414430
)
415431

@@ -428,7 +444,7 @@ srv_t_crosstable <- function(id, data, reporter, filter_panel_api, label, x, y,
428444
card$append_text("Comment", "header3")
429445
card$append_text(comment)
430446
}
431-
card$append_src(teal.code::get_code(output_q()))
447+
card$append_src(teal.code::get_code(req(decorated_output_q())))
432448
card
433449
}
434450
teal.reporter::simple_reporter_srv("simple_reporter", reporter = reporter, card_fun = card_fun)

man/tm_t_crosstable.Rd

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)