2222# ' This module generates the following objects, which can be modified in place using decorators:
2323# ' - `box_plot` (`ggplot2`)
2424# ' - `density_plot` (`ggplot2`)
25- # ' - `cum_dist_plot` (`ggplot2`)
25+ # ' - `cumulative_plot` (`ggplot2`)
26+ # ' - `table` ([DT::datatable()])
2627# '
2728# ' For additional details and examples of decorators, refer to the vignette
2829# ' `vignette("decorate-modules-output", package = "teal")` or the [`teal_transform_module()`] documentation.
@@ -178,8 +179,15 @@ tm_outliers <- function(label = "Outliers Module",
178179 checkmate :: assert_multi_class(pre_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
179180 checkmate :: assert_multi_class(post_output , c(" shiny.tag" , " shiny.tag.list" , " html" ), null.ok = TRUE )
180181
181- checkmate :: assert_list(decorators , " teal_transform_module" , null.ok = TRUE )
182-
182+ available_decorators <- c(" box_plot" , " density_plot" , " cumulative_plot" , " table" )
183+ if (checkmate :: test_list(decorators , " teal_transform_module" , null.ok = TRUE )) {
184+ decorators <- if (checkmate :: test_names(names(decorators ), subset.of = c(" default" , available_decorators ))) {
185+ lapply(decorators , list )
186+ } else {
187+ list (default = decorators )
188+ }
189+ }
190+ assert_decorators(decorators , null.ok = TRUE , names = available_decorators )
183191 # End of assertions
184192
185193 # Make UI args
@@ -322,7 +330,19 @@ ui_outliers <- function(id, ...) {
322330 uiOutput(ns(" ui_outlier_help" ))
323331 )
324332 ),
325- ui_transform_teal_data(ns(" decorate" ), transformators = args $ decorators ),
333+ conditionalPanel(
334+ condition = paste0(" input['" , ns(" tabs" ), " '] == 'Boxplot'" ),
335+ ui_decorate_teal_data(ns(" d_box_plot" ), decorators = subset_decorators(" box_plot" , args $ decorators ))
336+ ),
337+ conditionalPanel(
338+ condition = paste0(" input['" , ns(" tabs" ), " '] == 'Density Plot'" ),
339+ ui_decorate_teal_data(ns(" d_density_plot" ), decorators = subset_decorators(" density_plot" , args $ decorators ))
340+ ),
341+ conditionalPanel(
342+ condition = paste0(" input['" , ns(" tabs" ), " '] == 'Cumulative Distribution Plot'" ),
343+ ui_decorate_teal_data(ns(" d_cumulative_plot" ), decorators = subset_decorators(" cumulative_plot" , args $ decorators ))
344+ ),
345+ ui_decorate_teal_data(ns(" d_table" ), decorators = subset_decorators(" table" , args $ decorators )),
326346 teal.widgets :: panel_item(
327347 title = " Plot settings" ,
328348 selectInput(
@@ -585,7 +605,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
585605 )
586606 )
587607
588- if (length(categorical_var ) > 0 ) {
608+ qenv <- if (length(categorical_var ) > 0 ) {
589609 qenv <- teal.code :: eval_code(
590610 qenv ,
591611 substitute(
@@ -641,7 +661,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
641661 )
642662 }
643663
644- qenv <- teal.code :: eval_code(
664+ teal.code :: eval_code(
645665 qenv ,
646666 substitute(
647667 expr = {
@@ -669,16 +689,29 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
669689 tidyr :: pivot_longer(- categorical_var_name ) %> %
670690 tidyr :: pivot_wider(names_from = categorical_var , values_from = value ) %> %
671691 tibble :: column_to_rownames(" name" )
672- summary_table
673692 },
674693 env = list (
675694 categorical_var = categorical_var ,
676695 categorical_var_name = as.name(categorical_var )
677696 )
678697 )
679698 )
699+ } else {
700+ within(qenv , summary_table <- data.frame ())
680701 }
681702
703+ # Datatable is generated in qenv to allow for output decoration
704+ qenv <- within(qenv , {
705+ table <- DT :: datatable(
706+ summary_table ,
707+ options = list (
708+ dom = " t" ,
709+ autoWidth = TRUE ,
710+ columnDefs = list (list (width = " 200px" , targets = " _all" ))
711+ )
712+ )
713+ })
714+
682715 if (length(categorical_var ) > 0 && nrow(qenv [[" ANL_OUTLIER" ]]) > 0 ) {
683716 shinyjs :: show(" order_by_outlier" )
684717 } else {
@@ -688,26 +721,8 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
688721 qenv
689722 })
690723
691- output $ summary_table <- DT :: renderDataTable(
692- expr = {
693- if (iv_r()$ is_valid()) {
694- categorical_var <- as.vector(merged $ anl_input_r()$ columns_source $ categorical_var )
695- if (! is.null(categorical_var )) {
696- DT :: datatable(
697- common_code_q()[[" summary_table" ]],
698- options = list (
699- dom = " t" ,
700- autoWidth = TRUE ,
701- columnDefs = list (list (width = " 200px" , targets = " _all" ))
702- )
703- )
704- }
705- }
706- }
707- )
708-
709724 # boxplot/violinplot # nolint commented_code
710- boxplot_q <- reactive({
725+ box_plot_q <- reactive({
711726 req(common_code_q())
712727 ANL <- common_code_q()[[" ANL" ]]
713728 ANL_OUTLIER <- common_code_q()[[" ANL_OUTLIER" ]]
@@ -947,7 +962,7 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
947962 teal.code :: eval_code(
948963 qenv ,
949964 substitute(
950- expr = cum_dist_plot <- plot_call +
965+ expr = cumulative_plot <- plot_call +
951966 geom_point(data = outlier_points , aes(x = outlier_var_name , y = y , color = is_outlier_selected )) +
952967 scale_color_manual(values = c(" TRUE" = " red" , " FALSE" = " black" )) +
953968 labs + ggthemes + themes ,
@@ -962,37 +977,61 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
962977 )
963978 })
964979
965- final_q <- reactive({
966- req(input $ tabs )
967- tab_type <- input $ tabs
968- result_q <- if (tab_type == " Boxplot" ) {
969- boxplot_q()
970- } else if (tab_type == " Density Plot" ) {
971- density_plot_q()
972- } else if (tab_type == " Cumulative Distribution Plot" ) {
973- cumulative_plot_q()
974- }
975- # used to display table when running show-r-code code
976- # added after the plots so that a change in selected columns doesn't affect
977- # brush selection.
978- teal.code :: eval_code(
979- result_q ,
980- substitute(
981- expr = {
982- columns_index <- union(
983- setdiff(names(ANL_OUTLIER ), c(" is_outlier_selected" , " order" )),
984- table_columns
985- )
986- ANL_OUTLIER_EXTENDED [ANL_OUTLIER_EXTENDED $ is_outlier_selected , columns_index ]
987- },
988- env = list (
989- table_columns = input $ table_ui_columns
980+ current_tab_r <- reactive({
981+ switch (req(input $ tabs ),
982+ " Boxplot" = " box_plot" ,
983+ " Density Plot" = " density_plot" ,
984+ " Cumulative Distribution Plot" = " cumulative_plot"
985+ )
986+ })
987+
988+ post_expr <- reactive({
989+ substitute(
990+ expr = {
991+ columns_index <- union(
992+ setdiff(names(ANL_OUTLIER ), c(" is_outlier_selected" , " order" )),
993+ table_columns
990994 )
991- )
995+ ANL_OUTLIER_EXTENDED [ANL_OUTLIER_EXTENDED $ is_outlier_selected , columns_index ]
996+ print(.plot )
997+ },
998+ env = list (table_columns = input $ table_ui_columns , .plot = as.name(current_tab_r()))
992999 )
9931000 })
9941001
995- decorated_final_q <- srv_transform_teal_data(" decorate" , data = final_q , transformators = decorators )
1002+ decorated_q <- mapply(
1003+ function (obj_name , q ) {
1004+ srv_decorate_teal_data(
1005+ id = sprintf(" d_%s" , obj_name ),
1006+ data = q ,
1007+ decorators = subset_decorators(obj_name , decorators ),
1008+ expr = post_expr ,
1009+ expr_is_reactive = TRUE
1010+ )
1011+ },
1012+ rlang :: set_names(c(" box_plot" , " density_plot" , " cumulative_plot" )),
1013+ c(box_plot_q , density_plot_q , cumulative_plot_q )
1014+ )
1015+
1016+ decorated_final_q_no_table <- reactive(decorated_q [[req(current_tab_r())]]())
1017+
1018+ decorated_final_q <- srv_decorate_teal_data(
1019+ " d_table" ,
1020+ data = decorated_final_q_no_table ,
1021+ decorators = subset_decorators(" table" , decorators ),
1022+ expr = table
1023+ )
1024+
1025+ output $ summary_table <- DT :: renderDataTable(
1026+ expr = {
1027+ if (iv_r()$ is_valid()) {
1028+ categorical_var <- as.vector(merged $ anl_input_r()$ columns_source $ categorical_var )
1029+ if (! is.null(categorical_var )) {
1030+ decorated_final_q()[[" table" ]]
1031+ }
1032+ }
1033+ }
1034+ )
9961035
9971036 # slider text
9981037 output $ ui_outlier_help <- renderUI({
@@ -1042,25 +1081,22 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
10421081 }
10431082 })
10441083
1045- boxplot_r <- reactive({
1084+ box_plot_r <- reactive({
10461085 teal :: validate_inputs(iv_r())
1047- req(boxplot_q())
1048- decorated_final_q()[[" box_plot" ]]
1086+ req(decorated_q $ box_plot())[[" box_plot" ]]
10491087 })
10501088 density_plot_r <- reactive({
10511089 teal :: validate_inputs(iv_r())
1052- req(density_plot_q())
1053- decorated_final_q()[[" density_plot" ]]
1090+ req(decorated_q $ density_plot())[[" density_plot" ]]
10541091 })
10551092 cumulative_plot_r <- reactive({
10561093 teal :: validate_inputs(iv_r())
1057- req(cumulative_plot_q())
1058- decorated_final_q()[[" cum_dist_plot" ]]
1094+ req(decorated_q $ cumulative_plot())[[" cumulative_plot" ]]
10591095 })
10601096
10611097 box_pws <- teal.widgets :: plot_with_settings_srv(
10621098 id = " box_plot" ,
1063- plot_r = boxplot_r ,
1099+ plot_r = box_plot_r ,
10641100 height = plot_height ,
10651101 width = plot_width ,
10661102 brushing = TRUE
@@ -1106,16 +1142,20 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
11061142 ANL_OUTLIER_EXTENDED <- common_code_q()[[" ANL_OUTLIER_EXTENDED" ]]
11071143 ANL <- common_code_q()[[" ANL" ]]
11081144
1109- plot_brush <- if (tab == " Boxplot" ) {
1110- boxplot_r()
1111- box_pws $ brush()
1112- } else if (tab == " Density Plot" ) {
1113- density_plot_r()
1114- density_pws $ brush()
1115- } else if (tab == " Cumulative Distribution Plot" ) {
1116- cumulative_plot_r()
1117- cum_density_pws $ brush()
1118- }
1145+ plot_brush <- switch (current_tab_r(),
1146+ box_plot = {
1147+ box_plot_r()
1148+ box_pws $ brush()
1149+ },
1150+ density_plot = {
1151+ density_plot_r()
1152+ density_pws $ brush()
1153+ },
1154+ cumulative_plot = {
1155+ cumulative_plot_r()
1156+ cum_density_pws $ brush()
1157+ }
1158+ )
11191159
11201160 # removing unused column ASAP
11211161 ANL_OUTLIER $ order <- ANL $ order <- NULL
0 commit comments