Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates "Decorators" to use name-based execution and new wrappers #812

Merged
merged 31 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fb08fbf
feat: tm_g_scatterplot
averissimo Nov 26, 2024
82aeea5
feat: tm_a_pca
averissimo Nov 26, 2024
6561d03
feat: allow expression to be output of reactive
averissimo Nov 26, 2024
0b3b10b
fix: corrects assertion
averissimo Nov 26, 2024
8e262c3
feat: tm_g_bivariate
averissimo Nov 26, 2024
929f45f
feat: tm_g_response
averissimo Nov 26, 2024
ff7d3c2
feat: tm_g_scatterplotmatrix
averissimo Nov 26, 2024
7a96181
feat: tm_g_crosstable
averissimo Nov 26, 2024
e7cb0f1
feat: tm_data_table
averissimo Nov 26, 2024
b29e8d1
fix: when only 1 ui_decorate, default is the only accepted name in de…
averissimo Nov 27, 2024
72b5d05
feat: tm_g_association
averissimo Nov 27, 2024
7b8b8c0
feat: tm_g_association
averissimo Nov 27, 2024
ea3f729
docs: first try at changing documentation for decorators arg
averissimo Nov 27, 2024
6d5dea3
docs: typo with extra backtick
averissimo Nov 27, 2024
668af66
feat: tm_outliers
averissimo Nov 27, 2024
ea8d583
feat: unifying documentation
averissimo Nov 27, 2024
2f9f79b
feat: use common function to normalize decorators
averissimo Nov 27, 2024
bb52cf6
docs: update docs on other complex modules with more than 1 decoratea…
averissimo Nov 27, 2024
943c260
fix: use plot/table with only 1 output, instead of only relying on de…
averissimo Nov 27, 2024
039c37a
docs: generate man page
averissimo Nov 27, 2024
337c2af
feat: tm_a_pca plot object split in 4
averissimo Nov 27, 2024
f9c1d7b
chore: fix linter errors
averissimo Nov 27, 2024
9ec4381
feat: tm_g_distribution
averissimo Nov 27, 2024
34bc4cd
fix: normalize decorators
averissimo Nov 27, 2024
6f02f63
Update R/tm_g_distribution.R
averissimo Nov 28, 2024
33614b7
Update R/tm_g_distribution.R
averissimo Nov 28, 2024
64b61cf
Update R/tm_missing_data.R
averissimo Nov 28, 2024
64ccbce
chore: reorder parameters and rename function to be more R-like
averissimo Nov 28, 2024
1c8d0d7
chore: rename documentation from @m7pr
averissimo Nov 28, 2024
e4ad8a2
chore: remove unnecessary vars in favor of long roxygen2 line with co…
averissimo Nov 28, 2024
4d10d23
docs: add parameter documentation
averissimo Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions R/tm_a_pca.R
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,14 @@ tm_a_pca <- function(label = "Principal Component Analysis",
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)

checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)
if (checkmate::test_list(decorators, "teal_transform_module", null.ok = TRUE)) {
decorators <- if (checkmate::test_names(names(decorators), subset.of = c("default", "plot"))) {
lapply(decorators, list)
} else {
list(default = decorators)
}
}
assert_decorators(decorators, null.ok = TRUE, names = c("default", "plot"))
m7pr marked this conversation as resolved.
Show resolved Hide resolved
# End of assertions

# Make UI args
Expand Down Expand Up @@ -240,7 +247,7 @@ ui_a_pca <- function(id, ...) {
choices = args$plot_choices,
selected = args$plot_choices[1]
),
ui_transform_teal_data(ns("decorate"), transformators = args$decorators)
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators))
m7pr marked this conversation as resolved.
Show resolved Hide resolved
),
teal.widgets::panel_item(
title = "Pre-processing",
Expand Down Expand Up @@ -975,13 +982,14 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl
)
})

decorated_output_q_no_print <- srv_transform_teal_data("decorate", data = output_q, transformators = decorators)
decorated_output_q <- reactive(within(decorated_output_q_no_print(), expr = print(plot)))
decorated_output_q <- srv_decorate_teal_data(
id = "decorator",
data = output_q,
decorators = subset_decorators("plot", decorators),
expr = print(plot)
)

plot_r <- reactive({
req(output_q())
decorated_output_q()[["plot"]]
})
plot_r <- reactive(req(decorated_output_q())[["plot"]])

pws <- teal.widgets::plot_with_settings_srv(
id = "pca_plot",
Expand Down
90 changes: 48 additions & 42 deletions R/tm_g_bivariate.R
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,14 @@ tm_g_bivariate <- function(label = "Bivariate Plots",
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)

checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)
if (checkmate::test_list(decorators, "teal_transform_module", null.ok = TRUE)) {
decorators <- if (checkmate::test_names(names(decorators), subset.of = c("default", "plot"))) {
lapply(decorators, list)
} else {
list(default = decorators)
}
}
assert_decorators(decorators, null.ok = TRUE, names = c("default", "plot"))
# End of assertions

# Make UI args
Expand Down Expand Up @@ -350,7 +357,7 @@ ui_g_bivariate <- function(id, ...) {
justified = TRUE
)
),
ui_transform_teal_data(ns("decorate"), transformators = args$decorators),
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators)),
if (!is.null(args$row_facet) || !is.null(args$col_facet)) {
tags$div(
class = "data-extract-box",
Expand Down Expand Up @@ -665,47 +672,46 @@ srv_g_bivariate <- function(id,
teal.code::eval_code(merged$anl_q_r(), substitute(expr = plot <- cl, env = list(cl = cl)))
})

decorated_output_q <- srv_transform_teal_data("decorate", data = output_q, transformators = decorators)

decorated_output_q_facets <- reactive({
ANL <- merged$anl_q_r()[["ANL"]]
row_facet_name <- as.vector(merged$anl_input_r()$columns_source$row_facet)
col_facet_name <- as.vector(merged$anl_input_r()$columns_source$col_facet)

# Add labels to facets
nulled_row_facet_name <- varname_w_label(row_facet_name, ANL)
nulled_col_facet_name <- varname_w_label(col_facet_name, ANL)
facetting <- (isTRUE(input$facetting) && (!is.null(row_facet_name) || !is.null(col_facet_name)))
without_facet <- (is.null(nulled_row_facet_name) && is.null(nulled_col_facet_name)) || !facetting

print_call <- if (without_facet) {
quote(print(plot))
} else {
substitute(
expr = {
# Add facetting labels
# optional: grid.newpage() # nolint: commented_code.
# Prefixed with teal.modules.general as its usage will appear in "Show R code"
plot <- teal.modules.general::add_facet_labels(
plot,
xfacet_label = nulled_col_facet_name,
yfacet_label = nulled_row_facet_name
)
grid::grid.newpage()
grid::grid.draw(plot)
},
env = list(nulled_col_facet_name = nulled_col_facet_name, nulled_row_facet_name = nulled_row_facet_name)
)
}
decorated_output_q() %>%
teal.code::eval_code(print_call)
})

decorated_output_q_facets <- srv_decorate_teal_data(
"decorator",
data = output_q,
decorators = subset_decorators("plot", decorators),
expr = reactive({
averissimo marked this conversation as resolved.
Show resolved Hide resolved
ANL <- merged$anl_q_r()[["ANL"]]
row_facet_name <- as.vector(merged$anl_input_r()$columns_source$row_facet)
col_facet_name <- as.vector(merged$anl_input_r()$columns_source$col_facet)

# Add labels to facets
nulled_row_facet_name <- varname_w_label(row_facet_name, ANL)
nulled_col_facet_name <- varname_w_label(col_facet_name, ANL)
facetting <- (isTRUE(input$facetting) && (!is.null(row_facet_name) || !is.null(col_facet_name)))
without_facet <- (is.null(nulled_row_facet_name) && is.null(nulled_col_facet_name)) || !facetting

print_call <- if (without_facet) {
quote(print(plot))
} else {
substitute(
expr = {
# Add facetting labels
# optional: grid.newpage() # nolint: commented_code.
# Prefixed with teal.modules.general as its usage will appear in "Show R code"
plot <- teal.modules.general::add_facet_labels(
plot,
xfacet_label = nulled_col_facet_name,
yfacet_label = nulled_row_facet_name
)
grid::grid.newpage()
grid::grid.draw(plot)
},
env = list(nulled_col_facet_name = nulled_col_facet_name, nulled_row_facet_name = nulled_row_facet_name)
)
}
print_call
}),
expr_is_reactive = TRUE
)

plot_r <- reactive({
req(output_q())
decorated_output_q_facets()[["plot"]]
})
plot_r <- reactive(req(decorated_output_q_facets())[["plot"]])

pws <- teal.widgets::plot_with_settings_srv(
id = "myplot",
Expand Down
24 changes: 16 additions & 8 deletions R/tm_g_response.R
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,14 @@ tm_g_response <- function(label = "Response Plot",
checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)

checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)
if (checkmate::test_list(decorators, "teal_transform_module", null.ok = TRUE)) {
decorators <- if (checkmate::test_names(names(decorators), subset.of = c("default", "plot"))) {
lapply(decorators, list)
} else {
list(default = decorators)
}
}
assert_decorators(decorators, null.ok = TRUE, names = c("default", "plot"))
# End of assertions

# Make UI args
Expand Down Expand Up @@ -285,7 +292,7 @@ ui_g_response <- function(id, ...) {
selected = ifelse(args$freq, "frequency", "density"),
justified = TRUE
),
ui_transform_teal_data(ns("decorator"), transformators = args$decorators),
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators)),
teal.widgets::panel_group(
teal.widgets::panel_item(
title = "Plot settings",
Expand Down Expand Up @@ -552,13 +559,14 @@ srv_g_response <- function(id,
teal.code::eval_code(qenv, plot_call)
})

decorated_output_q <- srv_transform_teal_data(id = "decorator", data = output_q, transformators = decorators)
decorated_output_plot_q <- srv_decorate_teal_data(
id = "decorator",
data = output_q,
decorators = subset_decorators("plot", decorators),
expr = print(plot)
)

decorated_output_plot_q <- reactive(within(decorated_output_q(), print(plot)))
plot_r <- reactive({
req(output_q()) # Ensure original errors are displayed
decorated_output_plot_q()[["plot"]]
})
plot_r <- reactive(req(decorated_output_plot_q())[["plot"]])

# Insert the plot into a plot_with_settings module from teal.widgets
pws <- teal.widgets::plot_with_settings_srv(
Expand Down
27 changes: 19 additions & 8 deletions R/tm_g_scatterplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,16 @@ tm_g_scatterplot <- function(label = "Scatterplot",

checkmate::assert_scalar(table_dec)
checkmate::assert_class(ggplot2_args, "ggplot2_args")
checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)

if (checkmate::test_list(decorators, "teal_transform_module", null.ok = TRUE)) {
decorators <- if (checkmate::test_names(names(decorators), subset.of = c("default", "plot"))) {
lapply(decorators, list)
} else {
list(default = decorators)
}
}
assert_decorators(decorators, null.ok = TRUE, names = c("default", "plot"))

# End of assertions

# Make UI args
Expand Down Expand Up @@ -430,7 +439,7 @@ ui_g_scatterplot <- function(id, ...) {
is_single_dataset = is_single_dataset_value
)
},
ui_transform_teal_data(ns("decorator"), transformators = args$decorators),
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators)),
teal.widgets::panel_group(
teal.widgets::panel_item(
title = "Plot settings",
Expand Down Expand Up @@ -1005,12 +1014,14 @@ srv_g_scatterplot <- function(id,
teal.code::eval_code(plot_q, plot_call)
})

decorated_output_q <- srv_transform_teal_data(id = "decorator", data = output_q, transformators = decorators)
decorated_output_plot_q <- reactive(within(decorated_output_q(), print(plot)))
plot_r <- reactive({
req(output_q()) # Ensure original errors are displayed
decorated_output_plot_q()[["plot"]]
})
decorated_output_plot_q <- srv_decorate_teal_data(
id = "decorator",
data = output_q,
decorators = subset_decorators("plot", decorators),
expr = print(plot)
)

plot_r <- reactive(req(decorated_output_plot_q())[["plot"]])

# Insert the plot into a plot_with_settings module from teal.widgets
pws <- teal.widgets::plot_with_settings_srv(
Expand Down
26 changes: 18 additions & 8 deletions R/tm_g_scatterplotmatrix.R
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,15 @@ tm_g_scatterplotmatrix <- function(label = "Scatterplot Matrix",

checkmate::assert_multi_class(pre_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
checkmate::assert_multi_class(post_output, c("shiny.tag", "shiny.tag.list", "html"), null.ok = TRUE)
checkmate::assert_list(decorators, "teal_transform_module", null.ok = TRUE)

if (checkmate::test_list(decorators, "teal_transform_module", null.ok = TRUE)) {
decorators <- if (checkmate::test_names(names(decorators), subset.of = c("default", "plot"))) {
lapply(decorators, list)
} else {
list(default = decorators)
}
}
averissimo marked this conversation as resolved.
Show resolved Hide resolved
assert_decorators(decorators, null.ok = TRUE, names = c("default", "plot"))
# End of assertions

# Make UI args
Expand Down Expand Up @@ -249,7 +257,7 @@ ui_g_scatterplotmatrix <- function(id, ...) {
is_single_dataset = is_single_dataset_value
),
tags$hr(),
ui_transform_teal_data(ns("decorator"), transformators = args$decorators),
ui_decorate_teal_data(ns("decorator"), decorators = subset_decorators("plot", args$decorators)),
teal.widgets::panel_group(
teal.widgets::panel_item(
title = "Plot settings",
Expand Down Expand Up @@ -444,12 +452,14 @@ srv_g_scatterplotmatrix <- function(id,
qenv
})

decorated_output_q_no_print <- srv_transform_teal_data(id = "decorator", data = output_q, transformators = decorators)
decorated_output_q <- reactive(within(decorated_output_q_no_print(), print(plot)))
plot_r <- reactive({
req(output_q()) # Ensure original errors are displayed
m7pr marked this conversation as resolved.
Show resolved Hide resolved
decorated_output_q()[["plot"]]
})
decorated_output_q <- srv_decorate_teal_data(
id = "decorator",
data = output_q,
decorators = subset_decorators("plot", decorators),
expr = print(plot)
)

plot_r <- reactive(req(decorated_output_q())[["plot"]])

# Insert the plot into a plot_with_settings module
pws <- teal.widgets::plot_with_settings_srv(
Expand Down
8 changes: 6 additions & 2 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -286,19 +286,21 @@ assert_single_selection <- function(x,
#' @param expr (`expression` or `reactive`) to evaluate on the output of the decoration.
#' When an expression it must be inline code. See [within()]
#' Default is `NULL` which won't evaluate any appending code.
#' @param expr_is_reactive ()
averissimo marked this conversation as resolved.
Show resolved Hide resolved
#' @details
#' `srv_decorate_teal_data` is a wrapper around `srv_transform_teal_data` that
#' allows to decorate the data with additional expressions.
#' When original `teal_data` object is in error state, it will show that error
#' first.
#'
#' @keywords internal
srv_decorate_teal_data <- function(id, data, decorators, expr) {
srv_decorate_teal_data <- function(id, data, decorators, expr, expr_is_reactive = FALSE) {
assert_reactive(data)
checkmate::assert_list(decorators, "teal_transform_module")
checkmate::assert_flag(expr_is_reactive)

missing_expr <- missing(expr)
if (!missing_expr) {
if (!missing_expr && !expr_is_reactive) {
expr <- rlang::enexpr(expr)
}

Expand All @@ -310,6 +312,8 @@ srv_decorate_teal_data <- function(id, data, decorators, expr) {
req(data(), decorated_output())
if (missing_expr) {
decorated_output()
} else if (expr_is_reactive) {
eval_code(decorated_output(), expr())
} else {
eval_code(decorated_output(), expr)
}
Expand Down
4 changes: 3 additions & 1 deletion man/srv_decorate_teal_data.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading