Skip to content

Commit ce590d2

Browse files
Fixes failing "Add to Report" for modules that have DT table visualization (#900)
# Pull Request <!--- Replace `#nnn` with your issue link for reference. --> - Fixes #899 - Fixes #897 ### Changes description - Use of `rtables::df_to_tt` to produce report tables (that are decoratable) - Update decorators documentation to reflect - Minor code improvements that are marginally related (better variable name to separate `data` (raw data frame) from `table` (rtable or DT)) --------- Signed-off-by: André Veríssimo <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent c45be63 commit ce590d2

File tree

9 files changed

+120
-144
lines changed

9 files changed

+120
-144
lines changed

.lintr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
linters: linters_with_defaults(
22
line_length_linter = line_length_linter(120),
3-
cyclocomp_linter = NULL,
43
object_usage_linter = NULL,
54
object_name_linter = object_name_linter(styles = c("snake_case", "symbols"), regexes = c(ANL = "^ANL_?[0-9A-Z_]*$", ADaM = "^r?AD[A-Z]{2,3}_?[0-9]*$")),
65
indentation_linter = NULL

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# teal.modules.general 0.4.1.9015
22

3+
### Breaking changes
4+
5+
- Removed the `table` object decoration in `tm_missing_data` and `tm_outliers` (#899).
6+
- Removed the `summary_table` and `test_table` object decoration in `tm_g_distribution` (#897).
7+
8+
### Bug fixes
9+
10+
- Fixes "Add to Report" functionality in `tm_outliers`, `tm_missing_data` and `tm_g_distribution` modules (#899 and #897).
11+
312
# teal.modules.general 0.4.1
413

514
### Bug fixes

R/tm_g_bivariate.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ srv_g_bivariate <- function(id,
561561
datasets = data
562562
)
563563
qenv <- reactive(
564-
teal.code::eval_code(data(), 'library("ggplot2");library("dplyr");library("teal.modules.general")') # nolint quotes
564+
teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint: quotes.
565565
)
566566

567567
anl_merged_q <- reactive({

R/tm_g_distribution.R

Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
#' This module generates the following objects, which can be modified in place using decorators::
3232
#' - `histogram_plot` (`ggplot`)
3333
#' - `qq_plot` (`ggplot`)
34-
#' - `summary_table` (`datatables` created with [DT::datatable()])
35-
#' - `test_table` (`datatables` created with [DT::datatable()])
3634
#'
3735
#' A Decorator is applied to the specific output using a named list of `teal_transform_module` objects.
3836
#' The name of this list corresponds to the name of the output to which the decorator is applied.
@@ -43,9 +41,7 @@
4341
#' ..., # arguments for module
4442
#' decorators = list(
4543
#' histogram_plot = teal_transform_module(...), # applied only to `histogram_plot` output
46-
#' qq_plot = teal_transform_module(...), # applied only to `qq_plot` output
47-
#' summary_table = teal_transform_module(...), # applied only to `summary_table` output
48-
#' test_table = teal_transform_module(...) # applied only to `test_table` output
44+
#' qq_plot = teal_transform_module(...) # applied only to `qq_plot` output
4945
#' )
5046
#' )
5147
#' ```
@@ -194,8 +190,7 @@ tm_g_distribution <- function(label = "Distribution Module",
194190
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
195191
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
196192

197-
available_decorators <- c("histogram_plot", "qq_plot", "test_table", "summary_table")
198-
assert_decorators(decorators, names = available_decorators)
193+
assert_decorators(decorators, names = c("histogram_plot", "qq_plot"))
199194

200195
# End of assertions
201196

@@ -322,14 +317,6 @@ ui_distribution <- function(id, ...) {
322317
collapsed = FALSE
323318
)
324319
),
325-
ui_decorate_teal_data(
326-
ns("d_summary"),
327-
decorators = select_decorators(args$decorators, "summary_table")
328-
),
329-
ui_decorate_teal_data(
330-
ns("d_test"),
331-
decorators = select_decorators(args$decorators, "test_table")
332-
),
333320
conditionalPanel(
334321
condition = paste0("input['", ns("main_type"), "'] == 'Density'"),
335322
bslib::accordion_panel(
@@ -1284,24 +1271,31 @@ srv_distribution <- function(id,
12841271
# Summary table listing has to be created separately to allow for qenv join
12851272
output_summary_q <- reactive({
12861273
if (iv_r()$is_valid()) {
1287-
within(common_q(), summary_table <- DT::datatable(summary_table_data))
1274+
within(common_q(), {
1275+
summary_table <- rtables::df_to_tt(summary_table_data)
1276+
summary_table
1277+
})
12881278
} else {
1289-
within(common_q(), summary_table <- DT::datatable(summary_table_data[0L, ]))
1279+
within(
1280+
common_q(),
1281+
summary_table <- rtables::rtable(header = rtables::rheader(colnames(summary_table_data)))
1282+
)
12901283
}
12911284
})
12921285

12931286
output_test_q <- reactive({
12941287
# wrapped in if since could lead into validate error - we do want to continue
12951288
test_q_out <- try(test_q(), silent = TRUE)
1296-
if (!inherits(test_q_out, c("try-error", "error"))) {
1297-
c(
1289+
if (inherits(test_q_out, c("try-error", "error"))) {
1290+
within(
12981291
common_q(),
1299-
within(test_q_out, {
1300-
test_table <- DT::datatable(test_table_data)
1301-
})
1292+
test_table <- rtables::rtable(header = rtables::rheader("No data available in table"), rtables::rrow())
13021293
)
13031294
} else {
1304-
within(common_q(), test_table <- DT::datatable(data.frame(missing = character(0L))))
1295+
within(c(common_q(), test_q_out), {
1296+
test_table <- rtables::df_to_tt(test_table_data)
1297+
test_table
1298+
})
13051299
}
13061300
})
13071301

@@ -1319,54 +1313,47 @@ srv_distribution <- function(id,
13191313
expr = print(qq_plot)
13201314
)
13211315

1322-
decorated_output_summary_q <- srv_decorate_teal_data(
1323-
"d_summary",
1324-
data = output_summary_q,
1325-
decorators = select_decorators(decorators, "summary_table"),
1326-
expr = summary_table
1327-
)
1328-
1329-
decorated_output_test_q <- srv_decorate_teal_data(
1330-
"d_test",
1331-
data = output_test_q,
1332-
decorators = select_decorators(decorators, "test_table"),
1333-
expr = test_table
1334-
)
1335-
13361316
decorated_output_q <- reactive({
13371317
tab <- req(input$tabs) # tab is NULL upon app launch, hence will crash without this statement
13381318
test_q_out <- try(test_q(), silent = TRUE)
1339-
decorated_test_q_out <- if (inherits(test_q_out, c("try-error", "error"))) {
1340-
teal.code::qenv()
1341-
} else {
1342-
decorated_output_test_q()
1343-
}
1319+
test_q_out <- output_test_q()
13441320

13451321
out_q <- switch(tab,
13461322
Histogram = decorated_output_dist_q(),
13471323
QQplot = decorated_output_qq_q()
13481324
)
1349-
c(out_q, decorated_output_summary_q(), decorated_test_q_out)
1325+
c(out_q, output_summary_q(), test_q_out)
13501326
})
13511327

13521328
dist_r <- reactive(req(decorated_output_dist_q())[["histogram_plot"]])
13531329

13541330
qq_r <- reactive(req(decorated_output_qq_q())[["qq_plot"]])
13551331

1356-
output$summary_table <- DT::renderDataTable(
1357-
expr = decorated_output_summary_q()[["summary_table"]],
1358-
options = list(
1359-
autoWidth = TRUE,
1360-
columnDefs = list(list(width = "200px", targets = "_all"))
1361-
),
1362-
rownames = FALSE
1363-
)
1332+
summary_r <- reactive({
1333+
q <- req(output_summary_q())
1334+
1335+
list(
1336+
html = DT::datatable(
1337+
q[["summary_table_data"]],
1338+
options = list(
1339+
autoWidth = TRUE,
1340+
columnDefs = list(list(width = "200px", targets = "_all"))
1341+
),
1342+
rownames = FALSE
1343+
),
1344+
report = q[["summary_table"]]
1345+
)
1346+
})
1347+
1348+
output$summary_table <- DT::renderDataTable(summary_r()[["html"]])
13641349

13651350
tests_r <- reactive({
1366-
req(iv_r()$is_valid())
1367-
teal::validate_inputs(iv_r_dist())
1368-
req(test_q()) # Ensure original errors are displayed
1369-
decorated_output_test_q()[["test_table"]]
1351+
q <- req(output_test_q())
1352+
1353+
list(
1354+
html = DT::datatable(q[["test_table_data"]]),
1355+
report = q[["test_table"]]
1356+
)
13701357
})
13711358

13721359
pws1 <- teal.widgets::plot_with_settings_srv(
@@ -1385,7 +1372,7 @@ srv_distribution <- function(id,
13851372
brushing = FALSE
13861373
)
13871374

1388-
output$t_stats <- DT::renderDataTable(expr = tests_r())
1375+
output$t_stats <- DT::renderDataTable(tests_r()[["html"]])
13891376

13901377
# Render R code.
13911378
source_code_r <- reactive(teal.code::get_code(req(decorated_output_q())))
@@ -1412,11 +1399,11 @@ srv_distribution <- function(id,
14121399
card$append_plot(qq_r(), dim = pws2$dim())
14131400
}
14141401
card$append_text("Statistics table", "header3")
1415-
card$append_table(decorated_output_summary_q()[["summary_table"]])
1402+
card$append_table(summary_r()[["report"]])
14161403
tests_error <- tryCatch(expr = tests_r(), error = function(e) "error")
1417-
if (inherits(tests_error, "data.frame")) {
1404+
if (!identical(tests_error, "error")) {
14181405
card$append_text("Tests table", "header3")
1419-
card$append_table(tests_r())
1406+
card$append_table(tests_r()[["report"]])
14201407
}
14211408

14221409
if (!comment == "") {

R/tm_missing_data.R

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#' - `summary_plot` (`grob` created with [ggplot2::ggplotGrob()])
2424
#' - `combination_plot` (`grob` created with [ggplot2::ggplotGrob()])
2525
#' - `by_subject_plot` (`ggplot`)
26-
#' - `table` (`datatables` created with [DT::datatable()])
2726
#'
2827
#' A Decorator is applied to the specific output using a named list of `teal_transform_module` objects.
2928
#' The name of this list corresponds to the name of the output to which the decorator is applied.
@@ -35,8 +34,7 @@
3534
#' decorators = list(
3635
#' summary_plot = teal_transform_module(...), # applied only to `summary_plot` output
3736
#' combination_plot = teal_transform_module(...), # applied only to `combination_plot` output
38-
#' by_subject_plot = teal_transform_module(...), # applied only to `by_subject_plot` output
39-
#' table = teal_transform_module(...) # applied only to `table` output
37+
#' by_subject_plot = teal_transform_module(...) # applied only to `by_subject_plot` output
4038
#' )
4139
#' )
4240
#' ```
@@ -148,8 +146,7 @@ tm_missing_data <- function(label = "Missing data",
148146
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
149147
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
150148

151-
available_decorators <- c("summary_plot", "combination_plot", "by_subject_plot", "table")
152-
assert_decorators(decorators, names = available_decorators)
149+
assert_decorators(decorators, names = c("summary_plot", "combination_plot", "by_subject_plot"))
153150
# End of assertions
154151

155152
datanames_module <- if (identical(datanames, "all") || is.null(datanames)) {
@@ -429,8 +426,7 @@ encoding_missing_data <- function(id, summary_per_patient = FALSE, ggtheme, data
429426
choices = c("counts", "proportions"),
430427
selected = "counts",
431428
inline = TRUE
432-
),
433-
ui_decorate_teal_data(ns("dec_summary_table"), decorators = select_decorators(decorators, "table"))
429+
)
434430
),
435431
bslib::accordion(
436432
bslib::accordion_panel(
@@ -1143,7 +1139,10 @@ srv_missing_data <- function(id,
11431139
)
11441140
}
11451141

1146-
within(qenv, table <- DT::datatable(summary_data))
1142+
within(qenv, {
1143+
table <- rtables::df_to_tt(summary_data)
1144+
table
1145+
})
11471146
})
11481147

11491148
by_subject_plot_q <- reactive({
@@ -1285,13 +1284,6 @@ srv_missing_data <- function(id,
12851284
}
12861285
)
12871286

1288-
decorated_summary_table_q <- srv_decorate_teal_data(
1289-
id = "dec_summary_table",
1290-
data = summary_table_q,
1291-
decorators = select_decorators(decorators, "table"),
1292-
expr = table
1293-
)
1294-
12951287
decorated_by_subject_plot_q <- srv_decorate_teal_data(
12961288
id = "dec_by_subject_plot",
12971289
data = by_subject_plot_q,
@@ -1310,18 +1302,24 @@ srv_missing_data <- function(id,
13101302
})
13111303

13121304
summary_table_r <- reactive({
1313-
req(decorated_summary_table_q())
1314-
1315-
if (length(input$variables_select) == 0) {
1316-
# so that zeroRecords message gets printed
1317-
# using tibble as it supports weird column names, such as " "
1318-
DT::datatable(
1319-
tibble::tibble(` ` = logical(0)),
1320-
options = list(language = list(zeroRecords = "No variable selected."), pageLength = input$levels_table_rows)
1321-
)
1322-
} else {
1323-
decorated_summary_table_q()[["table"]]
1324-
}
1305+
q <- req(summary_table_q())
1306+
1307+
list(
1308+
html = if (length(input$variables_select) == 0) {
1309+
# so that zeroRecords message gets printed
1310+
# using tibble as it supports weird column names, such as " "
1311+
DT::datatable(
1312+
tibble::tibble(` ` = logical(0)),
1313+
options = list(
1314+
language = list(zeroRecords = "No variable selected."),
1315+
pageLength = input$levels_table_rows
1316+
)
1317+
)
1318+
} else {
1319+
DT::datatable(q[["summary_data"]])
1320+
},
1321+
report = q[["table"]]
1322+
)
13251323
})
13261324

13271325
by_subject_plot_r <- reactive({
@@ -1343,7 +1341,7 @@ srv_missing_data <- function(id,
13431341
width = plot_width
13441342
)
13451343

1346-
output$levels_table <- DT::renderDataTable(summary_table_r())
1344+
output$levels_table <- DT::renderDataTable(summary_table_r()[["html"]])
13471345

13481346
pws3 <- teal.widgets::plot_with_settings_srv(
13491347
id = "by_subject_plot",
@@ -1359,7 +1357,7 @@ srv_missing_data <- function(id,
13591357
} else if (sum_type == "Combinations") {
13601358
decorated_combination_plot_q()
13611359
} else if (sum_type == "By Variable Levels") {
1362-
decorated_summary_table_q()
1360+
summary_table_q()
13631361
} else if (sum_type == "Grouped by Subject") {
13641362
decorated_by_subject_plot_q()
13651363
}
@@ -1397,11 +1395,10 @@ srv_missing_data <- function(id,
13971395
card$append_plot(combination_plot_r(), dim = pws2$dim())
13981396
} else if (sum_type == "By Variable Levels") {
13991397
card$append_text("Table", "header3")
1400-
table <- decorated_summary_table_q()[["table"]]
1401-
if (nrow(table) == 0L) {
1398+
if (nrow(summary_table_q()[["summary_data"]]) == 0L) {
14021399
card$append_text("No data available for table.")
14031400
} else {
1404-
card$append_table(table)
1401+
card$append_table(summary_table_r()[["report"]])
14051402
}
14061403
} else if (sum_type == "Grouped by Subject") {
14071404
card$append_text("Plot", "header3")

0 commit comments

Comments
 (0)