From 3709c314bb30a7efe6ccfd6e32470cbecab3614c Mon Sep 17 00:00:00 2001 From: Emily de la Rua <59304861+edelarua@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:10:42 -0400 Subject: [PATCH] Add table formatting options to `g_lineplot()` - table relative height & font size (#1335) # Pull Request Fixes #1333 and #1334 --------- Co-authored-by: 27856297+dependabot-preview[bot]@users.noreply.github.com <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Davide Garolini --- NEWS.md | 5 + R/g_lineplot.R | 38 +- man/g_lineplot.Rd | 13 +- .../_snaps/g_lineplot/g_lineplot_cohorts.svg | 24 +- .../g_lineplot/g_lineplot_factor_levels.svg | 24 +- .../g_lineplot/g_lineplot_plot_only.svg | 149 ++++++ .../g_lineplot/g_lineplot_table_only.svg | 152 ++++++ .../_snaps/g_lineplot/g_lineplot_w_stats.svg | 436 +++++++++--------- tests/testthat/test-g_lineplot.R | 21 +- 9 files changed, 611 insertions(+), 251 deletions(-) create mode 100644 tests/testthat/_snaps/g_lineplot/g_lineplot_plot_only.svg create mode 100644 tests/testthat/_snaps/g_lineplot/g_lineplot_table_only.svg diff --git a/NEWS.md b/NEWS.md index fcdea30235..36a915d79a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,11 @@ * Added `"N_row"` as an optional input to `denom` in `s_count_occurrences()`. * Refactored `a_count_occurrences_by_grade()` to no longer use `make_afun()`. +### Enhancements +* Added `rel_height_plot` parameter to `g_lineplot()` to control the line plot height relative to annotation table height. +* Updated the `table_font_size` parameter of `g_lineplot()` to control the size of all text in the annotation table, including labels. +* Added `as_list` parameter to `g_lineplot()` to allow users to return the line plot and annotation table elements as a list instead of stacked for more complex customization. + ### Bug Fixes * Fixed bug in `a_summary()` causing non-unique `row_name` values to occur when multiple statistics are selected for count variables. diff --git a/R/g_lineplot.R b/R/g_lineplot.R index 3946896787..013bb735dd 100644 --- a/R/g_lineplot.R +++ b/R/g_lineplot.R @@ -2,7 +2,7 @@ #' #' @description `r lifecycle::badge("stable")` #' -#' Line plot with the optional table. +#' Line plot with optional table. #' #' @inheritParams argument_convention #' @param alt_counts_df (`data.frame` or `NULL`)\cr data set that will be used (only) @@ -72,6 +72,11 @@ #' @param col (`character`)\cr color(s). See `?ggplot2::aes_colour_fill_alpha` for example values. #' @param linetype (`character`)\cr line type(s). See `?ggplot2::aes_linetype_size_shape` for example values. #' @param errorbar_width (`numeric(1)`)\cr width of the error bars. +#' @param rel_height_plot (`proportion`)\cr proportion of total figure height to allocate to the line plot. +#' Relative height of annotation table is then `1 - rel_height_plot`. If `table = NULL`, this parameter is ignored. +#' @param as_list (`flag`)\cr whether the two `ggplot` objects should be returned as a list when `table` is not `NULL`. +#' If `TRUE`, a named list with two elements, `plot` and `table`, will be returned. If `FALSE` (default) the +#' annotation table is printed below the plot via [cowplot::plot_grid()]. #' #' @return A `ggplot` line plot (and statistics table if applicable). #' @@ -162,7 +167,9 @@ g_lineplot <- function(df, errorbar_width = 0.45, newpage = lifecycle::deprecated(), col = NULL, - linetype = NULL) { + linetype = NULL, + rel_height_plot = 0.5, + as_list = FALSE) { checkmate::assert_character(variables, any.missing = TRUE) checkmate::assert_character(mid, null.ok = TRUE) checkmate::assert_character(interval, null.ok = TRUE) @@ -174,6 +181,8 @@ g_lineplot <- function(df, checkmate::assert_number(errorbar_width, lower = 0) checkmate::assert_string(title, null.ok = TRUE) checkmate::assert_string(subtitle, null.ok = TRUE) + assert_proportion_value(rel_height_plot) + checkmate::assert_logical(as_list) if (!is.null(table)) { table_format <- get_formats_from_stats(table) @@ -462,9 +471,15 @@ g_lineplot <- function(df, axis.ticks = ggplot2::element_blank(), axis.title = ggplot2::element_blank(), axis.text.x = ggplot2::element_blank(), - axis.text.y = ggplot2::element_text(margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 5)), + axis.text.y = ggplot2::element_text( + size = table_font_size * ggplot2::.pt, + margin = ggplot2::margin(t = 0, r = 0, b = 0, l = 5) + ), strip.text = ggplot2::element_text(hjust = 0), - strip.text.x = ggplot2::element_text(margin = ggplot2::margin(1.5, 0, 1.5, 0, "pt")), + strip.text.x = ggplot2::element_text( + size = table_font_size * ggplot2::.pt, + margin = ggplot2::margin(1.5, 0, 1.5, 0, "pt") + ), strip.background = ggplot2::element_rect(fill = "grey95", color = NA), legend.position = "none" ) @@ -473,8 +488,19 @@ g_lineplot <- function(df, tbl <- tbl + ggplot2::facet_wrap(facets = group_var, ncol = 1) } - # align plot and table - cowplot::plot_grid(p, tbl, ncol = 1, align = "v", axis = "tblr") + if (!as_list) { + # align plot and table + cowplot::plot_grid( + p, + tbl, + ncol = 1, + align = "v", + axis = "tblr", + rel_heights = c(rel_height_plot, 1 - rel_height_plot) + ) + } else { + list(plot = p, table = tbl) + } } else { p } diff --git a/man/g_lineplot.Rd b/man/g_lineplot.Rd index c3f9b35921..4d1f8d84d3 100644 --- a/man/g_lineplot.Rd +++ b/man/g_lineplot.Rd @@ -38,7 +38,9 @@ g_lineplot( errorbar_width = 0.45, newpage = lifecycle::deprecated(), col = NULL, - linetype = NULL + linetype = NULL, + rel_height_plot = 0.5, + as_list = FALSE ) } \arguments{ @@ -149,6 +151,13 @@ appended to the plot. Names of \code{table_labels} must match the names of stati \item{col}{(\code{character})\cr color(s). See \code{?ggplot2::aes_colour_fill_alpha} for example values.} \item{linetype}{(\code{character})\cr line type(s). See \code{?ggplot2::aes_linetype_size_shape} for example values.} + +\item{rel_height_plot}{(\code{proportion})\cr proportion of total figure height to allocate to the line plot. +Relative height of annotation table is then \code{1 - rel_height_plot}. If \code{table = NULL}, this parameter is ignored.} + +\item{as_list}{(\code{flag})\cr whether the two \code{ggplot} objects should be returned as a list when \code{table} is not \code{NULL}. +If \code{TRUE}, a named list with two elements, \code{plot} and \code{table}, will be returned. If \code{FALSE} (default) the +annotation table is printed below the plot via \code{\link[cowplot:plot_grid]{cowplot::plot_grid()}}.} } \value{ A \code{ggplot} line plot (and statistics table if applicable). @@ -156,7 +165,7 @@ A \code{ggplot} line plot (and statistics table if applicable). \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} -Line plot with the optional table. +Line plot with optional table. } \examples{ diff --git a/tests/testthat/_snaps/g_lineplot/g_lineplot_cohorts.svg b/tests/testthat/_snaps/g_lineplot/g_lineplot_cohorts.svg index 2681f7be69..7c94921b6a 100644 --- a/tests/testthat/_snaps/g_lineplot/g_lineplot_cohorts.svg +++ b/tests/testthat/_snaps/g_lineplot/g_lineplot_cohorts.svg @@ -258,7 +258,7 @@ -C: Combination +C: Combination @@ -269,7 +269,7 @@ -B: Placebo +B: Placebo @@ -280,17 +280,17 @@ -A: Drug X +A: Drug X -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n diff --git a/tests/testthat/_snaps/g_lineplot/g_lineplot_factor_levels.svg b/tests/testthat/_snaps/g_lineplot/g_lineplot_factor_levels.svg index 75a04a6124..211945d4ee 100644 --- a/tests/testthat/_snaps/g_lineplot/g_lineplot_factor_levels.svg +++ b/tests/testthat/_snaps/g_lineplot/g_lineplot_factor_levels.svg @@ -257,7 +257,7 @@ -B: Placebo +B: Placebo @@ -268,7 +268,7 @@ -A: Drug X +A: Drug X @@ -279,17 +279,17 @@ -C: Combination +C: Combination -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n diff --git a/tests/testthat/_snaps/g_lineplot/g_lineplot_plot_only.svg b/tests/testthat/_snaps/g_lineplot/g_lineplot_plot_only.svg new file mode 100644 index 0000000000..9f2e8ddf8d --- /dev/null +++ b/tests/testthat/_snaps/g_lineplot/g_lineplot_plot_only.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +18 +19 +20 +21 +22 + + + + + + + + + + + +BASELINE +WEEK 1 DAY 8 +WEEK 2 DAY 15 +WEEK 3 DAY 22 +WEEK 4 DAY 29 +WEEK 5 DAY 36 + +Description of Planned Arm + + + + + + + + + +A: Drug X (N = 69) +B: Placebo (N = 73) +C: Combination (N = 58) +ALT (U/L) +Plot of Mean and 95% Confidence Limits by Visit + + diff --git a/tests/testthat/_snaps/g_lineplot/g_lineplot_table_only.svg b/tests/testthat/_snaps/g_lineplot/g_lineplot_table_only.svg new file mode 100644 index 0000000000..24f391cd0d --- /dev/null +++ b/tests/testthat/_snaps/g_lineplot/g_lineplot_table_only.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + +69 +19.2 +(18.10, 20.28) +69 +20.8 +(19.79, 21.76) +69 +19.6 +(18.53, 20.64) +69 +19.6 +(18.71, 20.55) +69 +20.3 +(19.32, 21.27) +69 +19.8 +(18.82, 20.76) + + + + + + + + + + +73 +20.3 +(19.30, 21.35) +73 +20.2 +(19.21, 21.10) +73 +20.7 +(19.60, 21.71) +73 +19.4 +(18.45, 20.36) +73 +20.4 +(19.34, 21.43) +73 +19.3 +(18.23, 20.30) + + + + + + + + + + +58 +19.2 +(18.12, 20.24) +58 +19.4 +(18.39, 20.33) +58 +20.0 +(19.09, 21.00) +58 +20.3 +(19.33, 21.30) +58 +21.0 +(19.74, 22.19) +58 +19.4 +(18.26, 20.46) + + + + + + + + + + +C: Combination + + + + + + + + + + +B: Placebo + + + + + + + + + + +A: Drug X + + +Mean 95% CI +Mean +n +Mean 95% CI +Mean +n +Mean 95% CI +Mean +n + + diff --git a/tests/testthat/_snaps/g_lineplot/g_lineplot_w_stats.svg b/tests/testthat/_snaps/g_lineplot/g_lineplot_w_stats.svg index 41a8c148b4..f675109528 100644 --- a/tests/testthat/_snaps/g_lineplot/g_lineplot_w_stats.svg +++ b/tests/testthat/_snaps/g_lineplot/g_lineplot_w_stats.svg @@ -23,275 +23,275 @@ - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -18 -19 -20 -21 -22 - - - - - - - - - - - -BASELINE -WEEK 1 DAY 8 -WEEK 2 DAY 15 -WEEK 3 DAY 22 -WEEK 4 DAY 29 -WEEK 5 DAY 36 -Time -Lab Test ALT (U/L) - -Description of Planned Arm - - - - - - - - - -A: Drug X (N = 69) -B: Placebo (N = 73) -C: Combination (N = 58) -Laboratory Test: ALT (U/L) -Plot of Mean and 80% Confidence Limits by Visit -caption +18 +19 +20 +21 +22 + + + + + + + + + + + +BASELINE +WEEK 1 DAY 8 +WEEK 2 DAY 15 +WEEK 3 DAY 22 +WEEK 4 DAY 29 +WEEK 5 DAY 36 +Time +Lab Test ALT (U/L) + +Description of Planned Arm + + + + + + + + + +A: Drug X (N = 69) +B: Placebo (N = 73) +C: Combination (N = 58) +Laboratory Test: ALT (U/L) +Plot of Mean and 80% Confidence Limits by Visit +caption - - + + - - + + - - + + - - -69 -19.2 -(18.48, 19.90) -69 -20.8 -(20.14, 21.42) -69 -19.6 -(18.90, 20.27) -69 -19.6 -(19.03, 20.23) -69 -20.3 -(19.67, 20.93) -69 -19.8 -(19.16, 20.42) + + +69 +19.2 +(18.48, 19.90) +69 +20.8 +(20.14, 21.42) +69 +19.6 +(18.90, 20.27) +69 +19.6 +(19.03, 20.23) +69 +20.3 +(19.67, 20.93) +69 +19.8 +(19.16, 20.42) - - + + - - -73 -20.3 -(19.66, 20.99) -73 -20.2 -(19.54, 20.77) -73 -20.7 -(19.97, 21.34) -73 -19.4 -(18.78, 20.02) -73 -20.4 -(19.71, 21.07) -73 -19.3 -(18.59, 19.93) + + +73 +20.3 +(19.66, 20.99) +73 +20.2 +(19.54, 20.77) +73 +20.7 +(19.97, 21.34) +73 +19.4 +(18.78, 20.02) +73 +20.4 +(19.71, 21.07) +73 +19.3 +(18.59, 19.93) - - + + - - -58 -19.2 -(18.49, 19.87) -58 -19.4 -(18.73, 19.99) -58 -20.0 -(19.43, 20.66) -58 -20.3 -(19.68, 20.95) -58 -21.0 -(20.17, 21.76) -58 -19.4 -(18.65, 20.07) + + +58 +19.2 +(18.49, 19.87) +58 +19.4 +(18.73, 19.99) +58 +20.0 +(19.43, 20.66) +58 +20.3 +(19.68, 20.95) +58 +21.0 +(20.17, 21.76) +58 +19.4 +(18.65, 20.07) - - + + - - -C: Combination + + +C: Combination - - + + - - -B: Placebo + + +B: Placebo - - + + - - -A: Drug X + + +A: Drug X -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n -Mean 80% CI -Mean -n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n +Mean 80% CI +Mean +n diff --git a/tests/testthat/test-g_lineplot.R b/tests/testthat/test-g_lineplot.R index 4ef5d541f1..b25cf60228 100644 --- a/tests/testthat/test-g_lineplot.R +++ b/tests/testthat/test-g_lineplot.R @@ -23,7 +23,9 @@ testthat::test_that("g_lineplot works with custom settings and statistics table" x_lab = "Time", y_lab = "Lab Test", subtitle = "Laboratory Test:", - caption = "caption" + caption = "caption", + table_font_size = 5.5, + rel_height_plot = 0.35 ) )) @@ -230,3 +232,20 @@ testthat::test_that("NA values are removed also from the table plot", { ) ) }) + +testthat::test_that("g_lineplot as_list argument works", { + testthat::expect_silent(g_lineplot_list <- withr::with_options( + opts_partial_match_old, + g_lineplot( + adlb, + adsl, + table = c("n", "mean", "mean_ci"), + as_list = TRUE + ) + )) + g_lineplot_plot_only <- g_lineplot_list$plot + g_lineplot_table_only <- g_lineplot_list$table + + expect_snapshot_ggplot("g_lineplot_plot_only", g_lineplot_plot_only, width = 10, height = 4) + expect_snapshot_ggplot("g_lineplot_table_only", g_lineplot_table_only, width = 9, height = 3) +})