diff --git a/DESCRIPTION b/DESCRIPTION index 804387e3f..25385cea2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -69,6 +69,7 @@ Imports: tools, utils Suggests: + formatters (>= 0.5.11), knitr (>= 1.42), logger (>= 0.4.0), nestcolor (>= 0.1.0), diff --git a/R/teal.modules.general.R b/R/teal.modules.general.R index 82f61a562..62c385d91 100644 --- a/R/teal.modules.general.R +++ b/R/teal.modules.general.R @@ -15,11 +15,11 @@ #' @keywords internal "_PACKAGE" -# nolint start +# nolint start. # Note ggmosaic (version <= 0.3.3) needs to be in DEPENDS as the following does not work if it is imported # df <- data.frame(x = c("A", "B", "C", "A"), y = c("Z", "Z", "W", "W")) # ggplot(df) + ggmosaic::geom_mosaic(aes(x = ggmosaic::product(x), fill = y)) -# nolint end +# nolint end. # Needed to avoid R CMD note on no visible binding utils::globalVariables("count") diff --git a/R/tm_a_pca.R b/R/tm_a_pca.R index d2dac0c08..ab842dd84 100644 --- a/R/tm_a_pca.R +++ b/R/tm_a_pca.R @@ -436,7 +436,7 @@ srv_a_pca <- function(id, data, dat, plot_height, plot_width, ggplot2_args, deco teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - teal.code::eval_code(obj, 'library("ggplot2");library("dplyr");library("tidyr")') # nolint: quotes + teal.code::eval_code(obj, "library(ggplot2);library(dplyr);library(tidyr)") }) anl_merged_q <- reactive({ req(anl_merged_input()) diff --git a/R/tm_a_regression.R b/R/tm_a_regression.R index d0ce394b3..9440fc0da 100644 --- a/R/tm_a_regression.R +++ b/R/tm_a_regression.R @@ -461,7 +461,7 @@ srv_a_regression <- function(id, teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - teal.code::eval_code(obj, 'library("ggplot2");library("dplyr")') # nolint: quotes + teal.code::eval_code(obj, "library(ggplot2);library(dplyr)") }) anl_merged_q <- reactive({ diff --git a/R/tm_data_table.R b/R/tm_data_table.R index 6fcfe4325..47d21cbfc 100644 --- a/R/tm_data_table.R +++ b/R/tm_data_table.R @@ -309,7 +309,7 @@ srv_data_table <- function(id, teal::validate_has_data(df, min_nrow = 1L, msg = paste("data", dataname, "is empty")) qenv <- teal.code::eval_code( data(), - 'library("dplyr");library("DT")' # nolint: quotes. + "library(dplyr);library(DT)" ) teal.code::eval_code( qenv, diff --git a/R/tm_g_association.R b/R/tm_g_association.R index 13d1c2372..67e5c5c4b 100644 --- a/R/tm_g_association.R +++ b/R/tm_g_association.R @@ -151,8 +151,8 @@ tm_g_association <- function(label = "Association", show_association = TRUE, plot_height = c(600, 400, 5000), plot_width = NULL, - distribution_theme = c("gray", "bw", "linedraw", "light", "dark", "minimal", "classic", "void"), # nolint: line_length. - association_theme = c("gray", "bw", "linedraw", "light", "dark", "minimal", "classic", "void"), # nolint: line_length. + distribution_theme = c("gray", "bw", "linedraw", "light", "dark", "minimal", "classic", "void"), # nolint line_length_linter. + association_theme = c("gray", "bw", "linedraw", "light", "dark", "minimal", "classic", "void"), # nolint line_length_linter. pre_output = NULL, post_output = NULL, ggplot2_args = teal.widgets::ggplot2_args(), @@ -345,7 +345,7 @@ srv_tm_g_association <- function(id, teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - teal.code::eval_code(obj, 'library("ggplot2");library("dplyr");library("ggmosaic")') # nolint: quotes + teal.code::eval_code(obj, "library(ggplot2);library(dplyr);library(ggmosaic)") }) anl_merged_q <- reactive({ req(anl_merged_input()) diff --git a/R/tm_g_bivariate.R b/R/tm_g_bivariate.R index bffecd3f3..ee25950ec 100644 --- a/R/tm_g_bivariate.R +++ b/R/tm_g_bivariate.R @@ -558,9 +558,9 @@ srv_g_bivariate <- function(id, teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - obj %>% - teal.code::eval_code('library("ggplot2");library("dplyr")') %>% - teal.code::eval_code(as.expression(anl_merged_input()$expr)) # don't mix char with expr in single eval_code + obj |> + teal.code::eval_code("library(ggplot2);library(dplyr)") |> + teal.code::eval_code(as.expression(anl_merged_input()$expr)) }) merged <- list( diff --git a/R/tm_g_distribution.R b/R/tm_g_distribution.R index 5fda712e6..61e4d38f4 100644 --- a/R/tm_g_distribution.R +++ b/R/tm_g_distribution.R @@ -523,7 +523,7 @@ srv_distribution <- function(id, ) qenv <- reactive( - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint quotes + teal.code::eval_code(data(), "library(ggplot2);library(dplyr)") ) anl_merged_q <- reactive({ @@ -663,7 +663,7 @@ srv_distribution <- function(id, "Group by variable must be `factor`, `character`, or `integer`" ) ) - qenv <- teal.code::eval_code(qenv, 'library("forcats")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(forcats)") qenv <- teal.code::eval_code( qenv, substitute( @@ -681,7 +681,7 @@ srv_distribution <- function(id, ) ) - qenv <- teal.code::eval_code(qenv, 'library("forcats")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(forcats)") qenv <- teal.code::eval_code( qenv, substitute( @@ -891,7 +891,7 @@ srv_distribution <- function(id, } if (length(t_dist) != 0 && main_type_var == "Density" && length(g_var) == 0 && length(s_var) == 0) { - qenv <- teal.code::eval_code(qenv, 'library("ggpp")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(ggpp)") qenv <- teal.code::eval_code( qenv, substitute( @@ -1037,7 +1037,7 @@ srv_distribution <- function(id, ) if (length(t_dist) != 0 && length(g_var) == 0 && length(s_var) == 0) { - qenv <- teal.code::eval_code(qenv, 'library("ggpp")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(ggpp)") qenv <- teal.code::eval_code( qenv, substitute( @@ -1233,7 +1233,7 @@ srv_distribution <- function(id, qenv <- common_q() if (length(s_var) == 0 && length(g_var) == 0) { - qenv <- teal.code::eval_code(qenv, 'library("generics")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(generics)") qenv <- teal.code::eval_code( qenv, substitute( @@ -1247,7 +1247,7 @@ srv_distribution <- function(id, ) ) } else { - qenv <- teal.code::eval_code(qenv, 'library("tidyr")') # nolint quotes + qenv <- teal.code::eval_code(qenv, "library(tidyr)") qenv <- teal.code::eval_code( qenv, substitute( diff --git a/R/tm_g_response.R b/R/tm_g_response.R index 12c0a96b9..6871565ac 100644 --- a/R/tm_g_response.R +++ b/R/tm_g_response.R @@ -387,7 +387,7 @@ srv_g_response <- function(id, ) qenv <- reactive( - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint quotes + teal.code::eval_code(data(), "library(ggplot2);library(dplyr)") ) anl_merged_q <- reactive({ @@ -520,7 +520,7 @@ srv_g_response <- function(id, resp_cl = resp_cl, hjust_value = if (swap_axes) "left" else "middle", vjust_value = if (swap_axes) "middle" else -1, - position_anl2_value = if (!freq) quote(position_fill(0.5)) else quote(position_stack(0.5)), # nolint: line_length. + position_anl2_value = if (!freq) quote(position_fill(0.5)) else quote(position_stack(0.5)), # nolint line_length_linter anl3_y = if (!freq) 1.1 else as.name("ns"), position_anl3_value = if (!freq) "fill" else "stack" ) diff --git a/R/tm_g_scatterplot.R b/R/tm_g_scatterplot.R index acb5c4890..7afd9f013 100644 --- a/R/tm_g_scatterplot.R +++ b/R/tm_g_scatterplot.R @@ -587,7 +587,7 @@ srv_g_scatterplot <- function(id, teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint quotes + teal.code::eval_code(data(), "library(ggplot2);library(dplyr)") }) anl_merged_q <- reactive({ diff --git a/R/tm_g_scatterplotmatrix.R b/R/tm_g_scatterplotmatrix.R index 1d7a2eb08..ae7ad79a8 100644 --- a/R/tm_g_scatterplotmatrix.R +++ b/R/tm_g_scatterplotmatrix.R @@ -330,7 +330,7 @@ srv_g_scatterplotmatrix <- function(id, teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - qenv <- teal.code::eval_code(obj, 'library("dplyr");library("lattice")') # nolint quotes + qenv <- teal.code::eval_code(obj, "library(dplyr);library(lattice)") teal.code::eval_code(qenv, as.expression(anl_merged_input()$expr)) }) diff --git a/R/tm_missing_data.R b/R/tm_missing_data.R index 46e7afa80..0de1fdb05 100644 --- a/R/tm_missing_data.R +++ b/R/tm_missing_data.R @@ -22,6 +22,7 @@ #' This module generates the following objects, which can be modified in place using decorators: #' - `summary_plot` (`ggplot`) #' - `combination_plot` (`grob` created with [ggplot2::ggplotGrob()]) +#' - `by_variable_plot` (`ggplot`) #' - `by_subject_plot` (`ggplot`) #' #' A Decorator is applied to the specific output using a named list of `teal_transform_module` objects. @@ -34,6 +35,7 @@ #' decorators = list( #' summary_plot = teal_transform_module(...), # applied only to `summary_plot` output #' combination_plot = teal_transform_module(...), # applied only to `combination_plot` output +#' by_variable_plot = teal_transform_module(...) # applied only to `by_variable_plot` output #' by_subject_plot = teal_transform_module(...) # applied only to `by_subject_plot` output #' ) #' ) @@ -228,6 +230,7 @@ srv_page_missing_data <- function(id, data, datanames, parent_dataname, }) output$dataset_encodings <- renderUI({ + req(ggtheme, datanames, is.logical(if_subject_plot)) tagList( lapply( datanames, @@ -314,8 +317,7 @@ ui_missing_data <- function(id, by_subject_plot = FALSE) { ), tabPanel( "By Variable Levels", - teal.widgets::get_dt_rows(ns("levels_table"), ns("levels_table_rows")), - DT::dataTableOutput(ns("levels_table")) + teal.widgets::plot_with_settings_ui(id = ns("by_variable_plot")) ) ) if (isTRUE(by_subject_plot)) { @@ -486,6 +488,7 @@ srv_missing_data <- function(id, }) data_parent_keys <- reactive({ + req(data(), parent_dataname) if (length(parent_dataname) > 0 && parent_dataname %in% names(data())) { keys <- teal.data::join_keys(data())[[dataname]] if (parent_dataname %in% names(keys)) { @@ -500,7 +503,7 @@ srv_missing_data <- function(id, common_code_q <- reactive({ teal::validate_inputs(iv_r()) - + req(data(), data_r(), input$summary_type) group_var <- input$group_by_var anl <- data_r() obj <- data() @@ -510,7 +513,7 @@ srv_missing_data <- function(id, ) qenv <- teal.code::eval_code(obj, { - 'library("dplyr");library("ggplot2");library("tidyr");library("gridExtra")' # nolint quotes + "library(dplyr);library(ggplot2);library(tidyr);library(gridExtra)" }) qenv <- if (!is.null(selected_vars()) && length(selected_vars()) != ncol(anl)) { @@ -566,13 +569,14 @@ srv_missing_data <- function(id, }) selected_vars <- reactive({ - req(input$variables_select) + req(data_keys(), input$variables_select) keys <- data_keys() vars <- unique(c(keys, input$variables_select)) vars }) vars_summary <- reactive({ + req(data_r()) na_count <- data_r() %>% sapply(function(x) mean(is.na(x)), USE.NAMES = TRUE) %>% sort(decreasing = TRUE) @@ -586,6 +590,7 @@ srv_missing_data <- function(id, # Keep encoding panel up-to-date output$variables <- renderUI({ + req(vars_summary(), data_r()) choices <- split(x = vars_summary()$key, f = vars_summary()$label, drop = TRUE) %>% rev() selected <- choices <- unname(unlist(choices)) @@ -600,6 +605,7 @@ srv_missing_data <- function(id, }) observeEvent(input$filter_na, { + req(vars_summary(), data_r()) choices <- vars_summary() %>% dplyr::select(!!as.name("key")) %>% getElement(name = 1) @@ -618,6 +624,7 @@ srv_missing_data <- function(id, }) output$group_by_var_ui <- renderUI({ + req(data_r()) all_choices <- teal.transform::variable_choices(data_r()) cat_choices <- all_choices[!sapply(data_r(), function(x) is.numeric(x) || inherits(x, "POSIXct"))] validate( @@ -638,10 +645,10 @@ srv_missing_data <- function(id, }) output$group_by_vals_ui <- renderUI({ - req(input$group_by_var) + req(isolate(prev_group_by_var()), input$group_by_var, data_r()) choices <- teal.transform::value_choices(data_r(), input$group_by_var, input$group_by_var) - prev_choices <- isolate(input$group_by_vals) + prev_choices <- req(isolate(input$group_by_vals)) # determine selected value based on filtered data # display those previously selected values that are still available @@ -674,8 +681,7 @@ srv_missing_data <- function(id, }) combination_cutoff_q <- reactive({ - req(common_code_q()) - qenv <- common_code_q() + qenv <- req(common_code_q()) teal.reporter::teal_card(qenv) <- c(teal.reporter::teal_card(qenv), "### Combination Plot") teal.code::eval_code( qenv, @@ -690,6 +696,7 @@ srv_missing_data <- function(id, }) output$cutoff <- renderUI({ + req(combination_cutoff_q()) x <- combination_cutoff_q()[["combination_cutoff"]]$n # select 10-th from the top @@ -713,9 +720,9 @@ srv_missing_data <- function(id, summary_plot_q <- reactive({ req(input$summary_type == "Summary") # needed to trigger update on tab change - teal::validate_has_data(data_r(), 1) - - qenv <- common_code_q() + teal::validate_has_data(req(data_r()), 1) + req(data_keys(), input$ggtheme) + qenv <- req(common_code_q()) if (input$any_na) { new_col_name <- "**anyna**" qenv <- teal.code::eval_code( @@ -764,7 +771,7 @@ srv_missing_data <- function(id, ) # always set "**anyna**" level as the last one - if (isolate(input$any_na)) { + if (req(isolate(input$any_na))) { qenv <- teal.code::eval_code( qenv, quote(x_levels <- c(setdiff(x_levels, "**anyna**"), "**anyna**")) @@ -920,8 +927,11 @@ srv_missing_data <- function(id, }) combination_plot_q <- reactive({ - req(input$summary_type == "Combinations", input$combination_cutoff, combination_cutoff_q()) - teal::validate_has_data(data_r(), 1) + req( + input$summary_type == "Combinations", input$combination_cutoff, + combination_cutoff_q(), data_keys(), input$ggtheme + ) + teal::validate_has_data(req(data_r()), 1) qenv <- teal.code::eval_code( combination_cutoff_q(), @@ -1054,12 +1064,12 @@ srv_missing_data <- function(id, }) }) - summary_table_q <- reactive({ + by_variable_plot_q <- reactive({ req( input$summary_type == "By Variable Levels", # needed to trigger update on tab change common_code_q() ) - teal::validate_has_data(data_r(), 1) + teal::validate_has_data(req(data_r()), 1) # extract the ANL dataset for use in further validation anl <- common_code_q()[["ANL"]] @@ -1090,13 +1100,13 @@ srv_missing_data <- function(id, function(x) round(sum(is.na(x)) / length(x), 4) } - qenv <- common_code_q() + qenv <- req(common_code_q()) teal.reporter::teal_card(qenv) <- c(teal.reporter::teal_card(qenv), "### Summary Table") qenv <- if (!is.null(group_var)) { common_code_libraries_q <- teal.code::eval_code( qenv, - 'library("forcats");library("glue")' # nolint + "library(forcats);library(glue)" ) teal.code::eval_code( common_code_libraries_q, @@ -1136,21 +1146,124 @@ srv_missing_data <- function(id, ) } - within(qenv, { - table <- rtables::df_to_tt(summary_data) - table - }) + dev_ggplot2_args <- teal.widgets::ggplot2_args( + labs = list( + fill = if (input$count_type == "counts") "Missing counts" else "Missing percentage", + y = NULL + ) + ) + + all_ggplot2_args <- teal.widgets::resolve_ggplot2_args( + user_plot = ggplot2_args[["By Variable Levels"]], + user_default = ggplot2_args$default, + module_plot = dev_ggplot2_args + ) + + parsed_ggplot2_args <- teal.widgets::parse_ggplot2_args( + all_ggplot2_args, + ggtheme = input$ggtheme + ) + + # convert to ggplot + labels <- lapply(qenv$ANL, attr, which = "label") + if (!any(lengths(labels))) { + ANL_q <- within(qenv, # nolint object_name_linter + { + keep_columns <- intersect(c(keys, group_var), colnames(ANL)) + ANL <- ANL %>% + filter(group_var_name %in% group_vals) %>% + pivot_longer(-keep_columns, values_transform = is.na) %>% + summarise( + .by = c(group_var_name, name), + value = sum(value), perc = value / n() + ) + }, + keys = join_keys(qenv) |> unlist() |> unique(), + group_var_name = as.name(group_var), + group_var = group_var, + group_vals = group_vals + ) + tile <- within(ANL_q, + { + by_variable_plot <- ggplot2::ggplot(ANL, ggplot2::aes(group_var_name, name)) + + ggplot2::geom_tile(ggplot2::aes(fill = column)) + + ggplot2::geom_text(ggplot2::aes(label = scales::percent(perc)), + data = . %>% dplyr::filter(perc > 0), color = "white" + ) + + ggplot2::scale_x_discrete(expand = ggplot2::expansion()) + + ggplot2::scale_fill_gradient(high = "#ff2951ff", low = "grey90", labels = labels) + + labs + + ggthemes + }, + group_var_name = as.name(group_var), + column = if (input$count_type == "counts") { + as.name("value") + } else { + as.name("perc") + }, + labs = parsed_ggplot2_args$labs, + labels = if (input$count_type == "counts") quote(ggplot2::waiver()) else quote(scales::label_percent()), + ggthemes = parsed_ggplot2_args$ggtheme + ) + } else { + ANL_q <- within(qenv, # nolint object_name_linter + { + keep_columns <- intersect(c(keys, group_var), colnames(ANL)) + labels <- vapply(qenv$ANL, attr, which = "label", FUN.VALUE = character(1L)) + ANL <- ANL %>% + dplyr::filter(group_var_name %in% group_vals) %>% + tidyr::pivot_longer(-keep_columns, values_transform = is.na) %>% + dplyr::summarise( + .by = c(group_var_name, name), + value = sum(value), perc = value / n() + ) %>% + dplyr::mutate(label = labels[name]) + }, + keys = join_keys(qenv) |> unlist() |> unique(), + group_var_name = as.name(group_var), + group_var = group_var, + group_vals = group_vals + ) + + tile <- within(ANL_q, + { + by_variable_plot <- ggplot2::ggplot(ANL, ggplot2::aes(group_var_name, label)) + + ggplot2::geom_tile(ggplot2::aes(fill = column)) + + ggplot2::geom_text(ggplot2::aes(label = scales::percent(perc)), + data = . %>% dplyr::filter(perc > 0), color = "white" + ) + + ggplot2::scale_x_discrete(expand = ggplot2::expansion()) + + ggplot2::scale_fill_gradient(high = "#ff2951ff", low = "grey90", labels = labels) + + labs + + ggthemes + }, + group_var_name = as.name(group_var), + column = if (input$count_type == "counts") { + as.name("value") + } else { + as.name("perc") + }, + labs = parsed_ggplot2_args$labs, + labels = if (input$count_type == "counts") quote(ggplot2::waiver()) else quote(scales::label_percent()), + ggthemes = parsed_ggplot2_args$ggtheme + ) + } + + tile }) by_subject_plot_q <- reactive({ # needed to trigger update on tab change - req(input$summary_type == "Grouped by Subject", common_code_q()) + req( + input$summary_type == "Grouped by Subject", common_code_q(), + input$ggtheme + ) - teal::validate_has_data(data_r(), 1) + teal::validate_has_data(req(data_r()), 1) dev_ggplot2_args <- teal.widgets::ggplot2_args( - labs = list(x = "", y = ""), - theme = list(legend.position = "bottom", axis.text.x = quote(ggplot2::element_blank())) + labs = list(x = NULL, y = NULL), + theme = list(legend.position = "bottom", axis.text.x = NULL) ) all_ggplot2_args <- teal.widgets::resolve_ggplot2_args( @@ -1171,7 +1284,7 @@ srv_missing_data <- function(id, function(x) paste(as.integer(x), collapse = "") } - qenv <- common_code_q() + qenv <- req(common_code_q()) teal.reporter::teal_card(qenv) <- c(teal.reporter::teal_card(qenv), "### By Subject Plot") qenv <- teal.code::eval_code( @@ -1285,11 +1398,11 @@ srv_missing_data <- function(id, }) ) - decorated_summary_table_q <- srv_decorate_teal_data( - id = "dec_summary_table", - data = summary_table_q, - decorators = select_decorators(decorators, "table"), - expr = quote(table) + decorated_by_variable_plot_q <- srv_decorate_teal_data( + id = "dec_by_variable_plot", + data = by_variable_plot_q, + decorators = select_decorators(decorators, "by_variable_plot"), + expr = quote(by_variable_plot) ) decorated_by_subject_plot_q <- srv_decorate_teal_data( @@ -1309,22 +1422,8 @@ srv_missing_data <- function(id, req(decorated_combination_plot_q())[["combination_plot"]] }) - summary_table_r <- reactive({ - q <- req(decorated_summary_table_q()) - - if (length(input$variables_select) == 0) { - # so that zeroRecords message gets printed - # using tibble as it supports weird column names, such as " " - DT::datatable( - tibble::tibble(` ` = logical(0)), - options = list( - language = list(zeroRecords = "No variable selected."), - pageLength = input$levels_table_rows - ) - ) - } else { - DT::datatable(q[["summary_data"]]) - } + by_variable_plot_r <- reactive({ + req(decorated_by_variable_plot_q())[["by_variable_plot"]] }) by_subject_plot_r <- reactive({ @@ -1346,9 +1445,14 @@ srv_missing_data <- function(id, width = plot_width ) - output$levels_table <- DT::renderDataTable(summary_table_r()) - pws3 <- teal.widgets::plot_with_settings_srv( + id = "by_variable_plot", + plot_r = by_variable_plot_r, + height = plot_height, + width = plot_width + ) + + pws4 <- teal.widgets::plot_with_settings_srv( id = "by_subject_plot", plot_r = by_subject_plot_r, height = plot_height, @@ -1360,8 +1464,11 @@ srv_missing_data <- function(id, decorated_combination_plot_dims_q <- # nolint: object_length_linter. set_chunk_dims(pws2, decorated_combination_plot_q) + decorated_by_variable_plot_dims_q <- # nolint: object_length_linter. + set_chunk_dims(pws3, decorated_by_variable_plot_q) + decorated_by_subject_plot_dims_q <- # nolint: object_length_linter. - set_chunk_dims(pws3, decorated_by_subject_plot_q) + set_chunk_dims(pws4, decorated_by_subject_plot_q) decorated_final_q <- reactive({ sum_type <- req(input$summary_type) @@ -1370,7 +1477,7 @@ srv_missing_data <- function(id, } else if (sum_type == "Combinations") { decorated_combination_plot_dims_q() } else if (sum_type == "By Variable Levels") { - decorated_summary_table_q() + decorated_by_variable_plot_dims_q() } else if (sum_type == "Grouped by Subject") { decorated_by_subject_plot_dims_q() } diff --git a/R/tm_outliers.R b/R/tm_outliers.R index ff67b4569..e53f021f4 100644 --- a/R/tm_outliers.R +++ b/R/tm_outliers.R @@ -452,7 +452,7 @@ srv_outliers <- function(id, data, outlier_var, req(anl_merged_input()) teal.code::eval_code( data_obj(), - 'library("dplyr");library("tidyr");library("tibble");library("ggplot2")' # nolint quotes + "library(dplyr);library(tidyr);library(tibble);library(ggplot2)" ) %>% teal.code::eval_code(as.expression(anl_merged_input()$expr)) }) @@ -738,10 +738,11 @@ srv_outliers <- function(id, data, outlier_var, categorical_var_name = as.name(categorical_var) ) ) - ) |> within({ - table <- rtables::df_to_tt(summary_data) - table - }) + ) |> + within({ + table <- rtables::df_to_tt(summary_data) + table + }) } else { msg <- "No categorical variable selected, summary table cannot be created." showNotification(msg, diff --git a/R/tm_t_crosstable.R b/R/tm_t_crosstable.R index 344326741..d0c8d395a 100644 --- a/R/tm_t_crosstable.R +++ b/R/tm_t_crosstable.R @@ -331,7 +331,7 @@ srv_t_crosstable <- function(id, data, label, x, y, remove_zero_columns, basic_t teal.reporter::teal_card(obj), teal.reporter::teal_card("## Module's output(s)") ) - teal.code::eval_code(obj, 'library("rtables");library("tern");library("dplyr")') # nolint quotes + teal.code::eval_code(obj, "library(rtables);library(tern);library(dplyr)") }) anl_merged_q <- reactive({ req(anl_merged_input()) diff --git a/man/tm_missing_data.Rd b/man/tm_missing_data.Rd index 25244f9c6..1b9543d2f 100644 --- a/man/tm_missing_data.Rd +++ b/man/tm_missing_data.Rd @@ -84,6 +84,7 @@ This module generates the following objects, which can be modified in place usin \itemize{ \item \code{summary_plot} (\code{ggplot}) \item \code{combination_plot} (\code{grob} created with \code{\link[ggplot2:ggplotGrob]{ggplot2::ggplotGrob()}}) +\item \code{by_variable_plot} (\code{ggplot}) \item \code{by_subject_plot} (\code{ggplot}) } @@ -96,6 +97,7 @@ See code snippet below: decorators = list( summary_plot = teal_transform_module(...), # applied only to `summary_plot` output combination_plot = teal_transform_module(...), # applied only to `combination_plot` output + by_variable_plot = teal_transform_module(...) # applied only to `by_variable_plot` output by_subject_plot = teal_transform_module(...) # applied only to `by_subject_plot` output ) ) diff --git a/tests/testthat/test-shinytest2-tm_misssing_data.R b/tests/testthat/test-shinytest2-tm_missing_data.R similarity index 99% rename from tests/testthat/test-shinytest2-tm_misssing_data.R rename to tests/testthat/test-shinytest2-tm_missing_data.R index 73d602f2b..4847feeb3 100644 --- a/tests/testthat/test-shinytest2-tm_misssing_data.R +++ b/tests/testthat/test-shinytest2-tm_missing_data.R @@ -14,7 +14,7 @@ app_driver_tm_missing_data <- function() { }) init_teal_app_driver( - teal::init( + app = init( data = data, modules = tm_missing_data( label = "Missing data", @@ -42,7 +42,6 @@ test_that("e2e - tm_missing_data: Initializes without errors", { app_driver <- app_driver_tm_missing_data() app_driver$expect_no_shiny_error() - testthat::expect_equal(app_driver$get_text(".teal-modules-tree .active"), "Missing data") encoding_dataset <- app_driver$get_text(paste(app_driver$namespaces(TRUE)$wrapper(NULL), ".help-block"))