diff --git a/DESCRIPTION b/DESCRIPTION index b74b4663f..684f47028 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -84,9 +84,10 @@ VignetteBuilder: knitr, rmarkdown Remotes: - insightsengineering/teal.reporter@main, + insightsengineering/teal.code@redesign@main, + insightsengineering/teal.reporter@redesign@main, insightsengineering/teal.widgets@main, - insightsengineering/teal@main + insightsengineering/teal@redesign@main Config/Needs/verdepcheck: haleyjeppson/ggmosaic, tidyverse/ggplot2, rstudio/shiny, insightsengineering/teal, insightsengineering/teal.slice, insightsengineering/teal.transform, diff --git a/R/tm_a_pca.R b/R/tm_a_pca.R index 8e4111cb5..2e468bc38 100644 --- a/R/tm_a_pca.R +++ b/R/tm_a_pca.R @@ -235,9 +235,6 @@ ui_a_pca <- function(id, ...) { uiOutput(ns("all_plots")) ), encoding = tags$div( - ### Reporter - teal.reporter::simple_reporter_ui(ns("simple_reporter")), - ### tags$label("Encodings", class = "text-primary"), teal.transform::datanames_input(args["dat"]), teal.transform::data_extract_ui( @@ -353,8 +350,7 @@ ui_a_pca <- function(id, ...) { } # Server function for the PCA module -srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, plot_width, ggplot2_args, decorators) { - with_reporter <- !missing(reporter) && inherits(reporter, "Reporter") +srv_a_pca <- function(id, data, filter_panel_api, dat, plot_height, plot_width, ggplot2_args, decorators) { with_filter <- !missing(filter_panel_api) && inherits(filter_panel_api, "FilterPanelAPI") checkmate::assert_class(data, "reactive") checkmate::assert_class(isolate(data()), "teal_data") @@ -436,13 +432,15 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl selector_list = selector_list, datasets = data ) + qenv <- reactive( - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr");library("tidyr")') # nolint quotes + teal.code::eval_code(data(), 'library("ggplot2");library("dplyr");library("tidyr")', label = "libraries") # nolint quotes ) + anl_merged_q <- reactive({ req(anl_merged_input()) qenv() %>% - teal.code::eval_code(as.expression(anl_merged_input()$expr)) + teal.code::eval_code(as.expression(anl_merged_input()$expr), label = "data preparations") }) merged <- list( @@ -496,38 +494,39 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl substitute( expr = keep_columns <- keep_cols, env = list(keep_cols = keep_cols) - ) + ), + label = "computation model" ) if (na_action == "drop") { qenv <- teal.code::eval_code( qenv, - quote(ANL <- tidyr::drop_na(ANL, keep_columns)) + quote(ANL <- tidyr::drop_na(ANL, keep_columns)), + label = "computation model" ) } - qenv <- teal.code::eval_code( + teal.code::eval_code( qenv, substitute( expr = pca <- summary(stats::prcomp(ANL[keep_columns], center = center, scale. = scale, retx = TRUE)), env = list(center = center, scale = scale) - ) - ) - - qenv <- teal.code::eval_code( - qenv, + ), + label = "computation model" + ) %>% + teal.code::eval_code( quote({ tbl_importance <- dplyr::as_tibble(pca$importance, rownames = "Metric") tbl_importance - }) - ) - + }), + label = "computation tbl imp" + ) %>% teal.code::eval_code( - qenv, quote({ tbl_eigenvector <- dplyr::as_tibble(pca$rotation, rownames = "Variable") tbl_eigenvector - }) + }), + label = "computation tbl eig" ) }) @@ -641,7 +640,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl labs = parsed_ggplot2_args$labs, themes = parsed_ggplot2_args$theme ) - ) + ), + label = "plot" ) } @@ -713,7 +713,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl labs = `if`(is.null(parsed_ggplot2_args$labs), quote(labs()), parsed_ggplot2_args$labs), themes = parsed_ggplot2_args$theme ) - ) + ), + label = "plot" ) } @@ -742,7 +743,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl substitute( expr = pca_rot <- dplyr::as_tibble(pca$x[, c(x_axis, y_axis)]), env = list(x_axis = x_axis, y_axis = y_axis) - ) + ), + label = "plot" ) # rot_vars = data frame that displays arrows in the plot, need to be scaled to data @@ -759,7 +761,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl dplyr::mutate_at(vars(c(x_axis, y_axis)), function(x) r * x / sqrt(max(v_scale))) }, env = list(x_axis = x_axis, y_axis = y_axis) - ) + ), + label = "plot" ) %>% teal.code::eval_code( if (is.logical(pca$center) && !pca$center) { @@ -778,13 +781,15 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl ) } else { quote(rot_vars <- rot_vars %>% dplyr::mutate(xstart = 0, ystart = 0)) - } + }, + label = "plot" ) %>% teal.code::eval_code( substitute( expr = rot_vars <- rot_vars %>% dplyr::filter(label %in% variables), env = list(variables = variables) - ) + ), + label = "plot" ) } @@ -813,7 +818,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl qenv <- teal.code::eval_code( qenv, - substitute(response <- ANL[[resp_col]], env = list(resp_col = resp_col)) + substitute(response <- ANL[[resp_col]], env = list(resp_col = resp_col)), + label = "plot" ) dev_labs <- list(color = varname_w_label(resp_col, ANL)) @@ -826,13 +832,15 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl ) { qenv <- teal.code::eval_code( qenv, - quote(pca_rot$response <- as.factor(response)) + quote(pca_rot$response <- as.factor(response)), + label = "plot" ) quote(ggplot2::scale_color_brewer(palette = "Dark2")) } else if (inherits(response, "Date")) { qenv <- teal.code::eval_code( qenv, - quote(pca_rot$response <- numeric(response)) + quote(pca_rot$response <- numeric(response)), + label = "plot" ) quote( @@ -845,7 +853,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl } else { qenv <- teal.code::eval_code( qenv, - quote(pca_rot$response <- response) + quote(pca_rot$response <- response), + label = "plot" ) quote(ggplot2::scale_color_gradient( low = c(getOption("ggplot2.discrete.colour")[2], "darkred")[1], @@ -931,7 +940,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl env = list( plot_call = Reduce(function(x, y) call("+", x, y), pca_plot_biplot_expr) ) - ) + ), + label = "plot" ) } @@ -1009,7 +1019,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl pc = pc, plot_call = Reduce(function(x, y) call("+", x, y), ggplot_exprs) ) - ) + ), + label = "plot" ) } @@ -1040,7 +1051,8 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl expr = reactive({ substitute(print(.plot), env = list(.plot = as.name(obj_name))) }), - expr_is_reactive = TRUE + expr_is_reactive = TRUE, + label = "plot" ) }, names(output_q), @@ -1133,30 +1145,38 @@ srv_a_pca <- function(id, data, reporter, filter_panel_api, dat, plot_height, pl title = "R Code for PCA" ) - ### REPORTER - if (with_reporter) { - card_fun <- function(comment, label) { - card <- teal::report_card_template( - title = "Principal Component Analysis Plot", - label = label, - with_filter = with_filter, - filter_panel_api = filter_panel_api - ) - card$append_text("Principal Components Table", "header3") - card$append_table(computation()[["tbl_importance"]]) - card$append_text("Eigenvectors Table", "header3") - card$append_table(computation()[["tbl_eigenvector"]]) - card$append_text("Plot", "header3") - card$append_plot(plot_r(), dim = pws$dim()) - if (!comment == "") { - card$append_text("Comment", "header3") - card$append_text(comment) - } - card$append_src(source_code_r()) - card - } - teal.reporter::simple_reporter_srv("simple_reporter", reporter = reporter, card_fun = card_fun) - } - ### + card_fun <- reactive({ + req(data(), decorated_output_q(), plot_r()) + + teal.reporter::report_document( + "## Setup", + teal.reporter::code_chunk(teal.code::get_code(data())), + + "## Libraries", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "libraries"), eval = TRUE), + + "## Data Preparations", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "data preparations")), + + "## PCA Model", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "computation model")), + + "### Principal Components Table", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "computation tbl imp")), + decorated_output_q()[["tbl_importance"]], + + "### Eigenvectors Table", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "computation tbl eig")), + decorated_output_q()[["tbl_eigenvector"]], + + "## PCA Plot", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "plot")), + plot_r() + ) + }) + + list( + report_card = card_fun + ) }) } diff --git a/R/tm_a_regression.R b/R/tm_a_regression.R index 5c0169e3b..86b94be68 100644 --- a/R/tm_a_regression.R +++ b/R/tm_a_regression.R @@ -285,9 +285,6 @@ ui_a_regression <- function(id, ...) { tags$div(verbatimTextOutput(ns("text"))) )), encoding = tags$div( - ### Reporter - teal.reporter::simple_reporter_ui(ns("simple_reporter")), - ### tags$label("Encodings", class = "text-primary"), tags$br(), teal.transform::datanames_input(args[c("response", "regressor")]), teal.transform::data_extract_ui( @@ -386,7 +383,6 @@ ui_a_regression <- function(id, ...) { # Server function for the regression module srv_a_regression <- function(id, data, - reporter, filter_panel_api, response, regressor, @@ -395,7 +391,6 @@ srv_a_regression <- function(id, ggplot2_args, default_outlier_label, decorators) { - with_reporter <- !missing(reporter) && inherits(reporter, "Reporter") with_filter <- !missing(filter_panel_api) && inherits(filter_panel_api, "FilterPanelAPI") checkmate::assert_class(data, "reactive") checkmate::assert_class(isolate(data()), "teal_data") @@ -463,15 +458,20 @@ srv_a_regression <- function(id, }) qenv <- reactive( - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint quotes + teal.code::eval_code( + data(), + 'library("ggplot2");library("dplyr")', # nolint quotes + label = "libraries" + ) ) anl_merged_q <- reactive({ req(anl_merged_input()) qenv() %>% - teal.code::eval_code(as.expression(anl_merged_input()$expr)) + teal.code::eval_code(as.expression(anl_merged_input()$expr), label = "data preparations") }) + # sets qenv object and populates it with data merge call and fit expression fit_r <- reactive({ ANL <- anl_merged_q()[["ANL"]] @@ -527,7 +527,7 @@ srv_a_regression <- function(id, } anl_merged_q() %>% - teal.code::eval_code(substitute(fit <- stats::lm(form, data = ANL), env = list(form = form))) %>% + teal.code::eval_code(substitute(fit <- stats::lm(form, data = ANL), env = list(form = form)), label = "fit") %>% teal.code::eval_code(quote({ for (regressor in names(fit$contrasts)) { alts <- paste0(levels(ANL[[regressor]]), collapse = "|") @@ -535,8 +535,8 @@ srv_a_regression <- function(id, paste0("^(", regressor, ")(", alts, ")$"), paste0("\\1", ": ", "\\2"), names(fit$coefficients) ) } - })) %>% - teal.code::eval_code(quote(summary(fit))) + }), label = "fit") %>% + teal.code::eval_code(quote(summary(fit)), label = "fit") }) label_col <- reactive({ @@ -589,7 +589,8 @@ srv_a_regression <- function(id, smoothy_aes <- ggplot2::aes_string(x = "x", y = "y") reg_form <- deparse(fit$call[[2]]) - }) + }), + label = "plot" ) }) @@ -659,7 +660,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -703,7 +705,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -762,7 +765,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -805,7 +809,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -871,7 +876,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -926,7 +932,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -976,7 +983,8 @@ srv_a_regression <- function(id, env = list( graph = Reduce(function(x, y) call("+", x, y), c(plot, parsed_ggplot2_args)) ) - ) + ), + label = "plot" ) }) @@ -996,8 +1004,9 @@ srv_a_regression <- function(id, decorated_output_q <- srv_decorate_teal_data( "decorator", data = output_q, - decorators = select_decorators(decorators, "plot"), - expr = print(plot) + decorators = select_decorators(decorators, "plot"), # decorator needs to put label="plot" in it's eval_code + expr = print(plot), + label = "plot" ) fitted <- reactive({ @@ -1025,7 +1034,6 @@ srv_a_regression <- function(id, ) }) - # Render R code. source_code_r <- reactive(teal.code::get_code(req(decorated_output_q()))) teal.widgets::verbatim_popup_srv( @@ -1035,25 +1043,72 @@ srv_a_regression <- function(id, ) ### REPORTER - if (with_reporter) { - card_fun <- function(comment, label) { - card <- teal::report_card_template( - title = "Linear Regression Plot", - label = label, - with_filter = with_filter, - filter_panel_api = filter_panel_api - ) - card$append_text("Plot", "header3") - card$append_plot(plot_r(), dim = pws$dim()) - if (!comment == "") { - card$append_text("Comment", "header3") - card$append_text(comment) - } - card$append_src(source_code_r()) - card - } - teal.reporter::simple_reporter_srv("simple_reporter", reporter = reporter, card_fun = card_fun) - } - ### + card_fun <- reactive({ + req(data(), decorated_output_q(), plot_r()) + teal.reporter::report_document( + + "## Setup", + teal.reporter::code_chunk(teal.code::get_code(data())), + + "## Libraries", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "libraries"), eval = TRUE), + + "## Data Preparations", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "data preparations"), eval = TRUE), + + "## Model", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "fit"), eval = TRUE), + teal.reporter::code_output( + paste(utils::capture.output(summary(teal.code::dev_suppress(fitted())))[-1], + collapse = "\n" + ) + ), + + "## Plot", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_q(), label = "plot")), + plot_r(), + + ### --- TODO: REST OF THIS CARD WILL BE DELETED + ### it is just here to test the reporter + + "## rtables for testing", + teal.reporter::code_chunk( + "rtables::rtable( + header = LETTERS[1:3], + rtables::rrow('one to three', 1, 2, 3), + rtables::rrow('more stuff', rtables::rcell(pi, format = 'xx.xx'), 'test', 'and more') + )" + ), + rtables::rtable( + header = LETTERS[1:3], + rtables::rrow("one to three", 1, 2, 3), + rtables::rrow("more stuff", rtables::rcell(pi, format = "xx.xx"), "test", "and more") + ), + + "## Table for testing", + teal.reporter::code_chunk( + "head(iris)" + ), + head(iris), + + "## keep_in_report", + + "If you don't want to include code for head(mtcars) in report - just don't include it.", + + "If you want the object to be kept in the report as loaded from .rds use keep_in_report()", + head(mtcars) |> keep_in_report(), + + "If you want the code/text to be included in the output, but not in the text use keep_in_report(FALSE)" |> + keep_in_report(FALSE), + teal.reporter::code_chunk( + "head(swiss)" + ) |> keep_in_report(FALSE) + + ) + }) + + list( + report_card = card_fun + ) }) } diff --git a/R/tm_g_scatterplot.R b/R/tm_g_scatterplot.R index 7fc1b3a37..92cd6aaf3 100644 --- a/R/tm_g_scatterplot.R +++ b/R/tm_g_scatterplot.R @@ -371,9 +371,6 @@ ui_g_scatterplot <- function(id, ...) { DT::dataTableOutput(ns("data_table"), width = "100%") ), encoding = tags$div( - ### Reporter - teal.reporter::simple_reporter_ui(ns("simple_reporter")), - ### tags$label("Encodings", class = "text-primary"), teal.transform::datanames_input(args[c("x", "y", "color_by", "size_by", "row_facet", "col_facet")]), teal.transform::data_extract_ui( @@ -509,7 +506,6 @@ ui_g_scatterplot <- function(id, ...) { # Server function for the scatterplot module srv_g_scatterplot <- function(id, data, - reporter, filter_panel_api, x, y, @@ -522,7 +518,6 @@ srv_g_scatterplot <- function(id, table_dec, ggplot2_args, decorators) { - with_reporter <- !missing(reporter) && inherits(reporter, "Reporter") with_filter <- !missing(filter_panel_api) && inherits(filter_panel_api, "FilterPanelAPI") checkmate::assert_class(data, "reactive") checkmate::assert_class(isolate(data()), "teal_data") @@ -590,15 +585,16 @@ srv_g_scatterplot <- function(id, datasets = data, merge_function = "dplyr::inner_join" ) + qenv <- reactive( - teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")') # nolint quotes + teal.code::eval_code(data(), 'library("ggplot2");library("dplyr")', label = "libraries") # nolint quotes ) anl_merged_q <- reactive({ req(anl_merged_input()) qenv() %>% - teal.code::eval_code(as.expression(anl_merged_input()$expr)) %>% - teal.code::eval_code(quote(ANL)) # used to display table when running show-r-code code + teal.code::eval_code(as.expression(anl_merged_input()$expr), label = "data preparations") %>% + teal.code::eval_code(quote(ANL), label = "data preparations") # used in show-r-code code }) merged <- list( @@ -769,7 +765,8 @@ srv_g_scatterplot <- function(id, log_x_fn = as.name(log_x_fn), log_x_var = paste0(log_x_fn, "_", x_var) ) - ) + ), + label = "plot" ) } @@ -784,7 +781,8 @@ srv_g_scatterplot <- function(id, log_y_fn = as.name(log_y_fn), log_y_var = paste0(log_y_fn, "_", y_var) ) - ) + ), + label = "plot" ) } @@ -913,7 +911,8 @@ srv_g_scatterplot <- function(id, substitute( expr = ANL <- dplyr::filter(ANL, !is.na(x_var) & !is.na(y_var)), env = list(x_var = as.name(x_var), y_var = as.name(y_var)) - ) + ), + label = "plot" ) } rhs_formula <- substitute( @@ -1016,14 +1015,15 @@ srv_g_scatterplot <- function(id, plot_call <- substitute(expr = plot <- plot_call, env = list(plot_call = plot_call)) - teal.code::eval_code(plot_q, plot_call) + teal.code::eval_code(plot_q, plot_call, label = "plot") }) decorated_output_plot_q <- srv_decorate_teal_data( id = "decorator", data = output_q, decorators = select_decorators(decorators, "plot"), - expr = print(plot) + expr = print(plot), + label = "plot" ) plot_r <- reactive(req(decorated_output_plot_q())[["plot"]]) @@ -1074,26 +1074,29 @@ srv_g_scatterplot <- function(id, title = "R Code for scatterplot" ) - ### REPORTER - if (with_reporter) { - card_fun <- function(comment, label) { - card <- teal::report_card_template( - title = "Scatter Plot", - label = label, - with_filter = with_filter, - filter_panel_api = filter_panel_api - ) - card$append_text("Plot", "header3") - card$append_plot(plot_r(), dim = pws$dim()) - if (!comment == "") { - card$append_text("Comment", "header3") - card$append_text(comment) - } - card$append_src(source_code_r()) - card - } - teal.reporter::simple_reporter_srv("simple_reporter", reporter = reporter, card_fun = card_fun) - } - ### + card_fun <- reactive({ + req(data(), req(decorated_output_plot_q()), plot_r()) + + teal.reporter::report_document( + + "## Setup", + teal.reporter::code_chunk(teal.code::get_code(data())), + + "## Libraries", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_plot_q(), label = "libraries"), eval = TRUE), + + "## Data Preparations", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_plot_q(), label = "data preparations")), + + "## Scatterplot", + teal.reporter::code_chunk(teal.code::get_code(decorated_output_plot_q(), label = "plot")), + plot_r() + + ) + }) + + list( + report_card = card_fun + ) }) } diff --git a/R/utils.R b/R/utils.R index 5eb3609fd..5296cd6fa 100644 --- a/R/utils.R +++ b/R/utils.R @@ -298,7 +298,7 @@ assert_single_selection <- function(x, #' first. #' #' @keywords internal -srv_decorate_teal_data <- function(id, data, decorators, expr, expr_is_reactive = FALSE) { +srv_decorate_teal_data <- function(id, data, decorators, expr, expr_is_reactive = FALSE, label = "") { checkmate::assert_class(data, classes = "reactive") checkmate::assert_list(decorators, "teal_transform_module") checkmate::assert_flag(expr_is_reactive) @@ -321,9 +321,9 @@ srv_decorate_teal_data <- function(id, data, decorators, expr, expr_is_reactive if (missing_expr) { decorated_output() } else if (expr_is_reactive) { - teal.code::eval_code(decorated_output(), expr()) + teal.code::eval_code(decorated_output(), expr(), label = label) } else { - teal.code::eval_code(decorated_output(), expr) + teal.code::eval_code(decorated_output(), expr, label = label) } } })