Skip to content

Commit 337c2af

Browse files
committed
feat: tm_a_pca plot object split in 4
1 parent 039c37a commit 337c2af

File tree

3 files changed

+125
-45
lines changed

3 files changed

+125
-45
lines changed

R/tm_a_pca.R

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,32 @@
2121
#' @section Decorating `tm_a_pca`:
2222
#'
2323
#' This module generates the following objects, which can be modified in place using decorators:
24-
#' - `plot` (`ggplot2`)
24+
#' - `elbow_plot` (`ggplot2`)
25+
#' - `circle_plot` (`ggplot2`)
26+
#' - `biplot` (`ggplot2`)
27+
#' - `eigenvector_plot` (`ggplot2`)
28+
#'
29+
#' Decorators can be applied to all outputs or only to specific objects using a
30+
#' named list of `teal_transform_module` objects.
31+
#' The `"default"` name is reserved for decorators that are applied to all outputs.
32+
#' See code snippet below:
33+
#'
34+
#' ```
35+
#' tm_a_pca(
36+
#' ..., # arguments for module
37+
#' decorators = list(
38+
#' default = list(teal_transform_module(...)), # applied to all outputs
39+
#' elbow_plot = list(teal_transform_module(...)), # applied only to `elbow_plot` output
40+
#' circle_plot = list(teal_transform_module(...)) # applied only to `circle_plot` output
41+
#' biplot = list(teal_transform_module(...)) # applied only to `biplot` output
42+
#' eigenvector_plot = list(teal_transform_module(...)) # applied only to `eigenvector_plot` output
43+
#' )
44+
#' )
45+
#' ```
2546
#'
2647
#' For additional details and examples of decorators, refer to the vignette
2748
#' `vignette("decorate-modules-output", package = "teal")` or the [`teal_transform_module()`] documentation.
2849
#'
29-
#'
3050
#' @examplesShinylive
3151
#' library(teal.modules.general)
3252
#' interactive <- function() TRUE
@@ -165,8 +185,9 @@ tm_a_pca <- function(label = "Principal Component Analysis",
165185
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
166186
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
167187

168-
decorators <- normalize_decorators(decorators, "plot")
169-
assert_decorators(decorators, null.ok = TRUE, "plot")
188+
available_decorators <- c("elbow_plot", "circle_plot", "biplot", "eigenvector_plot")
189+
decorators <- normalize_decorators(decorators, available_decorators)
190+
assert_decorators(decorators, null.ok = TRUE, available_decorators)
170191
# End of assertions
171192

172193
# Make UI args
@@ -241,7 +262,22 @@ ui_a_pca <- function(id, ...) {
241262
choices = args$plot_choices,
242263
selected = args$plot_choices[1]
243264
),
244-
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators))
265+
conditionalPanel(
266+
condition = sprintf("input['%s'] == 'Elbow plot'", ns("plot_type")),
267+
ui_decorate_teal_data(ns("d_elbow_plot"), decorators = subset_decorators("elbow_plot", args$decorators))
268+
),
269+
conditionalPanel(
270+
condition = sprintf("input['%s'] == 'Circle plot'", ns("plot_type")),
271+
ui_decorate_teal_data(ns("d_circle_plot"), decorators = subset_decorators("circle_plot", args$decorators))
272+
),
273+
conditionalPanel(
274+
condition = sprintf("input['%s'] == 'Biplot'", ns("plot_type")),
275+
ui_decorate_teal_data(ns("d_biplot"), decorators = subset_decorators("biplot", args$decorators))
276+
),
277+
conditionalPanel(
278+
condition = sprintf("input['%s'] == 'Eigenvector plot'", ns("plot_type")),
279+
ui_decorate_teal_data(ns("d_eigenvector_plot"), decorators = subset_decorators("eigenvector_plot", args$decorators))
280+
)
245281
),
246282
teal.widgets::panel_item(
247283
title = "Pre-processing",
@@ -566,7 +602,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
566602
)
567603

568604
cols <- c(getOption("ggplot2.discrete.colour"), c("lightblue", "darkred", "black"))[1:3]
569-
plot <- ggplot(mapping = aes_string(x = "component", y = "value")) +
605+
elbow_plot <- ggplot(mapping = aes_string(x = "component", y = "value")) +
570606
geom_bar(
571607
aes(fill = "Single variance"),
572608
data = dplyr::filter(elb_dat, metric == "Proportion of Variance"),
@@ -643,7 +679,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
643679
y = sin(seq(0, 2 * pi, length.out = 100))
644680
)
645681

646-
plot <- ggplot(pca_rot) +
682+
circle_plot <- ggplot(pca_rot) +
647683
geom_point(aes_string(x = x_axis, y = y_axis)) +
648684
geom_label(
649685
aes_string(x = x_axis, y = y_axis, label = "label"),
@@ -875,7 +911,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
875911
qenv,
876912
substitute(
877913
expr = {
878-
plot <- plot_call
914+
biplot <- plot_call
879915
},
880916
env = list(
881917
plot_call = Reduce(function(x, y) call("+", x, y), pca_plot_biplot_expr)
@@ -884,8 +920,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
884920
)
885921
}
886922

887-
# plot pc_var ----
888-
plot_pc_var <- function(base_q) {
923+
# plot eigenvector_plot ----
924+
plot_eigenvector <- function(base_q) {
889925
pc <- input$pc
890926
ggtheme <- input$ggtheme
891927

@@ -951,7 +987,7 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
951987
expr = {
952988
pca_rot <- pca$rotation[, pc, drop = FALSE] %>%
953989
dplyr::as_tibble(rownames = "Variable")
954-
plot <- plot_call
990+
eigenvector_plot <- plot_call
955991
},
956992
env = list(
957993
pc = pc,
@@ -961,29 +997,55 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
961997
)
962998
}
963999

964-
# plot final ----
965-
output_q <- reactive({
966-
req(computation())
967-
teal::validate_inputs(iv_r())
968-
teal::validate_inputs(iv_extra, header = "Plot settings are required")
1000+
# qenvs ---
1001+
output_q <- lapply(
1002+
list(
1003+
elbow_plot = plot_elbow,
1004+
circle_plot = plot_circle,
1005+
biplot = plot_biplot,
1006+
eigenvector_plot = plot_eigenvector
1007+
),
1008+
function(fun) {
1009+
reactive({
1010+
req(computation())
1011+
teal::validate_inputs(iv_r())
1012+
teal::validate_inputs(iv_extra, header = "Plot settings are required")
1013+
fun(computation())
1014+
})
1015+
}
1016+
)
9691017

970-
switch(input$plot_type,
971-
"Elbow plot" = plot_elbow(computation()),
972-
"Circle plot" = plot_circle(computation()),
973-
"Biplot" = plot_biplot(computation()),
974-
"Eigenvector plot" = plot_pc_var(computation()),
1018+
decorated_q <- mapply(
1019+
function(obj_name, q) {
1020+
srv_decorate_teal_data(
1021+
id = sprintf("d_%s", obj_name),
1022+
data = q,
1023+
decorators = subset_decorators(obj_name, decorators),
1024+
expr = reactive({
1025+
substitute(print(.plot), env = list(.plot = as.name(obj_name)))
1026+
}),
1027+
expr_is_reactive = TRUE
1028+
)
1029+
},
1030+
names(output_q),
1031+
output_q
1032+
)
1033+
1034+
# plot final ----
1035+
decorated_output_q <- reactive({
1036+
switch(req(input$plot_type),
1037+
"Elbow plot" = decorated_q$elbow_plot(),
1038+
"Circle plot" = decorated_q$circle_plot(),
1039+
"Biplot" = decorated_q$biplot(),
1040+
"Eigenvector plot" = decorated_q$eigenvector_plot(),
9751041
stop("Unknown plot")
9761042
)
9771043
})
9781044

979-
decorated_output_q <- srv_decorate_teal_data(
980-
id = "decorator",
981-
data = output_q,
982-
decorators = subset_decorators("plot", decorators),
983-
expr = print(plot)
984-
)
985-
986-
plot_r <- reactive(req(decorated_output_q())[["plot"]])
1045+
plot_r <- reactive({
1046+
plot_name <- gsub(" ", "_", tolower(req(input$plot_type)))
1047+
req(decorated_output_q())[[plot_name]]
1048+
})
9871049

9881050
pws <- teal.widgets::plot_with_settings_srv(
9891051
id = "pca_plot",

R/tm_outliers.R

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -996,27 +996,25 @@ srv_outliers <- function(id, data, reporter, filter_panel_api, outlier_var,
996996
)
997997
})
998998

999-
post_expr <- reactive({
1000-
substitute(
1001-
expr = {
1002-
columns_index <- union(
1003-
setdiff(names(ANL_OUTLIER), c("is_outlier_selected", "order")),
1004-
table_columns
1005-
)
1006-
ANL_OUTLIER_EXTENDED[ANL_OUTLIER_EXTENDED$is_outlier_selected, columns_index]
1007-
print(.plot)
1008-
},
1009-
env = list(table_columns = input$table_ui_columns, .plot = as.name(current_tab_r()))
1010-
)
1011-
})
1012-
1013999
decorated_q <- mapply(
10141000
function(obj_name, q) {
10151001
srv_decorate_teal_data(
10161002
id = sprintf("d_%s", obj_name),
10171003
data = q,
10181004
decorators = subset_decorators(obj_name, decorators),
1019-
expr = post_expr,
1005+
expr = reactive({
1006+
substitute(
1007+
expr = {
1008+
columns_index <- union(
1009+
setdiff(names(ANL_OUTLIER), c("is_outlier_selected", "order")),
1010+
table_columns
1011+
)
1012+
ANL_OUTLIER_EXTENDED[ANL_OUTLIER_EXTENDED$is_outlier_selected, columns_index]
1013+
print(.plot)
1014+
},
1015+
env = list(table_columns = input$table_ui_columns, .plot = as.name(obj_name))
1016+
)
1017+
}),
10201018
expr_is_reactive = TRUE
10211019
)
10221020
},

man/tm_a_pca.Rd

Lines changed: 21 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)