From 7c72df40d18e22c25ba0bd60b08b3d48f81c151f Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 25 Sep 2024 21:01:28 -0700 Subject: [PATCH 1/5] updates --- R/tbl_ard_summary.R | 13 +++++++-- tests/testthat/_snaps/tbl_ard_summary.md | 11 +++++++ tests/testthat/test-tbl_ard_summary.R | 37 ++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/R/tbl_ard_summary.R b/R/tbl_ard_summary.R index 0934e0fc6..50adeef75 100644 --- a/R/tbl_ard_summary.R +++ b/R/tbl_ard_summary.R @@ -165,6 +165,15 @@ tbl_ard_summary <- function(cards, ) |> deframe() |> as.list() + # for non-standard ARDs, fill in the missing default types + for (v in setdiff(include, names(default_types))) { + if (!"variable_level" %in% names(cards) || + is_empty(compact(dplyr::filter(cards, .data$variable %in%.env$v)$variable_level))) { + default_types[[v]] <- "continuous" + } + else default_types[[v]] <- "categorical" # styler: off + } + if (exists("v")) remove("v") # styler: off # process arguments ---------------------------------------------------------- cards::process_formula_selectors( @@ -187,14 +196,14 @@ tbl_ard_summary <- function(cards, walk( include, function(variable) { - if (default_types[[variable]] %in% "continuous" && + if (isTRUE(default_types[[variable]] %in% "continuous") && !type[[variable]] %in% c("continuous", "continuous2")) { cli::cli_abort( "Summary type for variable {.val {variable}} must be one of {.val {c('continuous', 'continuous2')}}, not {.val {type[[variable]]}}.", call = get_cli_abort_call() ) - } else if (default_types[[variable]] %in% c("categorical", "dichotomous") && + } else if (isTRUE(default_types[[variable]] %in% c("categorical", "dichotomous")) && !identical(type[[variable]], default_types[[variable]])) { cli::cli_abort( "Summary type for variable {.val {variable}} must be diff --git a/tests/testthat/_snaps/tbl_ard_summary.md b/tests/testthat/_snaps/tbl_ard_summary.md index 1d03a09af..916f88472 100644 --- a/tests/testthat/_snaps/tbl_ard_summary.md +++ b/tests/testthat/_snaps/tbl_ard_summary.md @@ -163,3 +163,14 @@ Error in `tbl_ard_summary()`: ! Variable "AGE" is type `continuous` and `statistic` argument value must be a string of length one. +# tbl_ard_summary() non-standard ARDs (ie not 'continuous', 'categorical', etc) + + Code + as.data.frame(tbl_ard_summary(ard, by = trt, statistic = ~"{estimate}")) + Output + **Characteristic** **Drug A** **Drug B** + 1 time + 2 12 90.8 86.3 + 3 24 46.9 41.2 + 4 age 47.0 47.4 + diff --git a/tests/testthat/test-tbl_ard_summary.R b/tests/testthat/test-tbl_ard_summary.R index 29590c892..9c6a16449 100644 --- a/tests/testthat/test-tbl_ard_summary.R +++ b/tests/testthat/test-tbl_ard_summary.R @@ -297,3 +297,40 @@ test_that("tbl_ard_summary() existing 'gts_column'", { ) }) +test_that("tbl_ard_summary() non-standard ARDs (ie not 'continuous', 'categorical', etc)", { + # This ARD was created with this code: + # cards::bind_ard( + # survival::survfit(survival::Surv(ttdeath, death) ~ trt, trial) |> + # cardx::ard_survival_survfit(times = c(12, 24)) |> + # dplyr::filter(stat_name %in% c("estimate")) |> + # dplyr::mutate( + # fmt_fn = list("xx.x%"), + # group1_level = unlist(group1_level) |> as.character() |> as.list() + # ), + # cardx::ard_stats_t_test_onesample(trial, variables = age, by = trt) |> + # dplyr::filter(stat_name %in% c("estimate")) + # ) |> + # dplyr::select(-cards::all_missing_columns()) |> + # dput() + + ard <- + structure(list(group1 = c("trt", "trt", "trt", "trt", "trt", + "trt"), group1_level = list("Drug A", "Drug A", "Drug B", "Drug B", + "Drug A", "Drug B"), variable = c("time", "time", "time", + "time", "age", "age"), variable_level = list(12, 24, 12, 24, + NULL, NULL), context = c("survival", "survival", "survival", + "survival", "stats_t_test_onesample", "stats_t_test_onesample" + ), stat_name = c("estimate", "estimate", "estimate", "estimate", + "estimate", "estimate"), stat_label = c("Survival Probability", + "Survival Probability", "Survival Probability", "Survival Probability", + "Mean", "Mean"), stat = list(0.908163265306122, 0.46938775510204, + 0.862745098039216, 0.411764705882353, c(`mean of x` = 47.010989010989), + c(`mean of x` = 47.4489795918367)), fmt_fn = list("xx.x%", + "xx.x%", "xx.x%", "xx.x%", 1L, 1L)), row.names = c(NA, -6L + ), class = c("card", "tbl_df", "tbl", "data.frame")) + + expect_snapshot( + tbl_ard_summary(ard, by = trt, statistic = ~ "{estimate}") |> + as.data.frame() + ) +}) From 662c21008e084c9bb859577d92a7eb5b296d2583 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 25 Sep 2024 21:07:39 -0700 Subject: [PATCH 2/5] Update NEWS.md --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 36940afee..16f2fc74f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # gtsummary (development version) +* Update in `tbl_ard_summary()` to better handle non-standard ARDs (i.e. not our typical continuous or categorical summaries) by assigning them a default summary type. (#1991) + * Made the `oneway.test()` available in `add_p.tbl_continuous()`. (#1970) * Added argument `tbl_ard_summary(overall)`. When `TRUE`, the ARD is parsed into primary ARD and the Overall ARD and we run `tbl_ard_summary() |> add_overall()`. (#1940) From eda75026a459221e16d12ca5c5cdb69c304e8a67 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Wed, 25 Sep 2024 21:31:04 -0700 Subject: [PATCH 3/5] spelling updates --- DESCRIPTION | 1 + NEWS.md | 4 ++-- R/add_p.R | 2 +- R/assign_tests.R | 2 +- R/tbl_uvregression.R | 2 +- R/theme_gtsummary.R | 4 ++-- inst/WORDLIST | 31 ++++++++++++++++++++++++------- man/add_p.tbl_summary.Rd | 2 +- man/assign_tests.Rd | 2 +- man/tbl_uvregression.Rd | 2 +- man/theme_gtsummary.Rd | 4 ++-- tests/spelling.R | 3 +++ 12 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 tests/spelling.R diff --git a/DESCRIPTION b/DESCRIPTION index 762687568..f3ba12195 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -80,6 +80,7 @@ Suggests: parsnip (>= 0.1.7), rmarkdown, smd (>= 0.6.6), + spelling, survey (>= 4.2), survival (>= 3.6-4), testthat (>= 3.2.0), diff --git a/NEWS.md b/NEWS.md index 16f2fc74f..14bce3a48 100644 --- a/NEWS.md +++ b/NEWS.md @@ -140,7 +140,7 @@ Updates to address regressions in the v2.0.0 release: * Added `pkgdown_print.gtsummary()` method that is only registered when the pkgdown package is loaded. This enables printing of gtsummary tables on the pkgdown site in the Examples section. (#1771) -* The package now uses updated `survey::svyquantile()` function to calculate quatiles, which was introduced in survey v4.1 +* The package now uses updated `survey::svyquantile()` function to calculate quantiles, which was introduced in survey v4.1 ### Bug fixes @@ -172,7 +172,7 @@ Updates to address regressions in the v2.0.0 release: * Arguments `modify_header(update)`, `modify_footnote(update)`, `modify_spanning_header(update)`, and `modify_fmt_fun(update)` have been deprecated. Use dynamic dots instead, e.g. `modify_header(...)`, which has been the preferred method for passing updates for a few years. -* Function `continuous_summary()` has been deprecated immediately. Apologies for the inconvenience of the immeidate deprecation. The way the function originally worked is not compatible with the updated internal structures. In most cases, users can use the `tbl_continuous()` function instead. +* Function `continuous_summary()` has been deprecated immediately. Apologies for the inconvenience of the immediate deprecation. The way the function originally worked is not compatible with the updated internal structures. In most cases, users can use the `tbl_continuous()` function instead. * Arguments `add_stat(fmt_fun, header, footnote, new_col_name)` have been deprecated since v1.4.0 (2021-04-13). They have now been fully removed from the package. diff --git a/R/add_p.R b/R/add_p.R index b3e85d85d..e4507b677 100644 --- a/R/add_p.R +++ b/R/add_p.R @@ -56,7 +56,7 @@ add_p <- function(x, ...) { #' @section test argument: #' #' See the [?tests][tests] help file for details on available tests and creating custom tests. -#' The [?tests][tests] help file also includes psuedo-code for each test to be clear +#' The [?tests][tests] help file also includes pseudo-code for each test to be clear #' precisely how the calculation is performed. #' #' The default test used in `add_p()` primarily depends on these factors: diff --git a/R/assign_tests.R b/R/assign_tests.R index 2696b4007..8c6806559 100644 --- a/R/assign_tests.R +++ b/R/assign_tests.R @@ -22,7 +22,7 @@ #' @param cont_variable (`string`)\cr #' a column name of the continuous summary variable in `tbl_continuous()` #' @param summary_type (named `list`)\cr -#' naemd list of summary types +#' named list of summary types #' @inheritParams cli::cli_abort #' #' @return A table of class `'gtsummary'` diff --git a/R/tbl_uvregression.R b/R/tbl_uvregression.R index 15efddb3d..c8dfa1a09 100644 --- a/R/tbl_uvregression.R +++ b/R/tbl_uvregression.R @@ -40,7 +40,7 @@ #' is the dependent variable, and `{x}` represents a single covariate. For a #' random intercept model, the formula may be `formula = "{y} ~ {x} + (1 | gear)"`. #' @param method.args (named `list`)\cr -#' Named list of arguments assed to `method`. +#' Named list of arguments passed to `method`. #' @param hide_n (scalar `logical`)\cr #' Hide N column. Default is `FALSE` #' @inheritParams tbl_regression diff --git a/R/theme_gtsummary.R b/R/theme_gtsummary.R index 18c13cb44..0c63c5b3e 100644 --- a/R/theme_gtsummary.R +++ b/R/theme_gtsummary.R @@ -8,7 +8,7 @@ #' @param set_theme (scalar `logical`)\cr #' Logical indicating whether to set the theme. Default is `TRUE`. #' When `FALSE` the named list of theme elements is returned invisibly -#' @param font_size (scaler `numeric`)\cr +#' @param font_size (scalar `numeric`)\cr #' Numeric font size for compact theme. #' Default is 13 for gt tables, and 8 for all other output types #' @@ -29,7 +29,7 @@ #' - `tbl_summary()` all percentages rounded to one decimal place #' - `tbl_regression()`,`tbl_uvregression()` add significance stars with `add_significance_stars()`; #' hides CI and p-value from output -#' - For flaxtable and huxtable output, the coeficient's standard error is placed below. For gt, it is placed to the right. +#' - For flextable and huxtable output, the coefficients' standard error is placed below. For gt, it is placed to the right. #' - `theme_gtsummary_compact()` #' - tables printed with gt, flextable, kableExtra, or huxtable will be compact with smaller font size and reduced cell padding #' - `theme_gtsummary_printer(print_engine)` diff --git a/inst/WORDLIST b/inst/WORDLIST index 02cd8668a..4e37e5f20 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -1,14 +1,23 @@ ANCOVA +ARD +ARDs +Agresti +BH Biostatistics +CDISC CMD Codecov +Coull DOI GGally GVIF Gehan Hmisc JAMA +Jeffreys Kaplan +Lifecycle +Likert MacOS McNemar McNemar's @@ -21,20 +30,22 @@ RJ RStudio RTF Rao +Rmarkdown SHA Tarone Tidiers +Univariable VIF Waerden's Wainberg YAML +bonferroni bstfun +cardx cli codebase coef conf -coxph -crosstab customizability customizable der @@ -44,27 +55,30 @@ dplyr effectsize emmeans exponentiate +fdr flextable forcats ftExtra ggplot ggstats -glm +hochberg +holm +hommel huxtable kable kableExtra knitr labelled lifecycle -lm +likert +linebreaks lme -logLik mL -mira +mis nevent ng nnet -obejcts +pkgdown pre pvalue quosure @@ -80,11 +94,14 @@ th tibble tibbles tidiers +tidycmprsk tidyr tidyselect tidyselect's tidyverse +tilda un +unhidden unhide unicode univariable diff --git a/man/add_p.tbl_summary.Rd b/man/add_p.tbl_summary.Rd index 1db0fe514..3acc68e6a 100644 --- a/man/add_p.tbl_summary.Rd +++ b/man/add_p.tbl_summary.Rd @@ -60,7 +60,7 @@ Adds p-values to tables created by \code{\link[=tbl_summary]{tbl_summary()}} by See the \link[=tests]{?tests} help file for details on available tests and creating custom tests. -The \link[=tests]{?tests} help file also includes psuedo-code for each test to be clear +The \link[=tests]{?tests} help file also includes pseudo-code for each test to be clear precisely how the calculation is performed. The default test used in \code{add_p()} primarily depends on these factors: diff --git a/man/assign_tests.Rd b/man/assign_tests.Rd index 759b17d8f..574a8b067 100644 --- a/man/assign_tests.Rd +++ b/man/assign_tests.Rd @@ -62,7 +62,7 @@ Default is \code{NULL}.} Variables to include in adjusted calculations (e.g. in ANCOVA models).} \item{summary_type}{(named \code{list})\cr -naemd list of summary types} +named list of summary types} \item{calling_fun}{(\code{string})\cr Must be one of \code{'add_p'} and \code{'add_difference'}. Depending on the context, diff --git a/man/tbl_uvregression.Rd b/man/tbl_uvregression.Rd index 9b2b3050d..32569622c 100644 --- a/man/tbl_uvregression.Rd +++ b/man/tbl_uvregression.Rd @@ -67,7 +67,7 @@ Regression method or function, e.g. \link{lm}, \link{glm}, \link[survival:coxph] Methods may be passed as functions (\code{method=lm}) or as strings (\code{method='lm'}).} \item{method.args}{(named \code{list})\cr -Named list of arguments assed to \code{method}.} +Named list of arguments passed to \code{method}.} \item{exponentiate}{(scalar \code{logical})\cr Logical indicating whether to exponentiate the coefficient estimates. diff --git a/man/theme_gtsummary.Rd b/man/theme_gtsummary.Rd index 620304d12..afa3c5e31 100644 --- a/man/theme_gtsummary.Rd +++ b/man/theme_gtsummary.Rd @@ -50,7 +50,7 @@ theme_gtsummary_eda(set_theme = TRUE) Logical indicating whether to set the theme. Default is \code{TRUE}. When \code{FALSE} the named list of theme elements is returned invisibly} -\item{font_size}{(scaler \code{numeric})\cr +\item{font_size}{(scalar \code{numeric})\cr Numeric font size for compact theme. Default is 13 for gt tables, and 8 for all other output types} @@ -124,7 +124,7 @@ for details. \item \code{tbl_regression()},\code{tbl_uvregression()} add significance stars with \code{add_significance_stars()}; hides CI and p-value from output \itemize{ -\item For flaxtable and huxtable output, the coeficient's standard error is placed below. For gt, it is placed to the right. +\item For flextable and huxtable output, the coefficients' standard error is placed below. For gt, it is placed to the right. } } } diff --git a/tests/spelling.R b/tests/spelling.R new file mode 100644 index 000000000..6713838fc --- /dev/null +++ b/tests/spelling.R @@ -0,0 +1,3 @@ +if(requireNamespace('spelling', quietly = TRUE)) + spelling::spell_check_test(vignettes = TRUE, error = FALSE, + skip_on_cran = TRUE) From ab7e1f37443a989ff2276e95eebaea94bd3eeb15 Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Thu, 26 Sep 2024 08:09:43 -0700 Subject: [PATCH 4/5] Update test-tbl_ard_summary.R --- tests/testthat/test-tbl_ard_summary.R | 43 +++++++++------------------ 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/tests/testthat/test-tbl_ard_summary.R b/tests/testthat/test-tbl_ard_summary.R index 9c6a16449..dcb4cf7b1 100644 --- a/tests/testthat/test-tbl_ard_summary.R +++ b/tests/testthat/test-tbl_ard_summary.R @@ -298,36 +298,21 @@ test_that("tbl_ard_summary() existing 'gts_column'", { }) test_that("tbl_ard_summary() non-standard ARDs (ie not 'continuous', 'categorical', etc)", { - # This ARD was created with this code: - # cards::bind_ard( - # survival::survfit(survival::Surv(ttdeath, death) ~ trt, trial) |> - # cardx::ard_survival_survfit(times = c(12, 24)) |> - # dplyr::filter(stat_name %in% c("estimate")) |> - # dplyr::mutate( - # fmt_fn = list("xx.x%"), - # group1_level = unlist(group1_level) |> as.character() |> as.list() - # ), - # cardx::ard_stats_t_test_onesample(trial, variables = age, by = trt) |> - # dplyr::filter(stat_name %in% c("estimate")) - # ) |> - # dplyr::select(-cards::all_missing_columns()) |> - # dput() + skip_if_not(is_pkg_installed(c("cardx", "survival", "broom"), reference_pkg = "gtsummary")) - ard <- - structure(list(group1 = c("trt", "trt", "trt", "trt", "trt", - "trt"), group1_level = list("Drug A", "Drug A", "Drug B", "Drug B", - "Drug A", "Drug B"), variable = c("time", "time", "time", - "time", "age", "age"), variable_level = list(12, 24, 12, 24, - NULL, NULL), context = c("survival", "survival", "survival", - "survival", "stats_t_test_onesample", "stats_t_test_onesample" - ), stat_name = c("estimate", "estimate", "estimate", "estimate", - "estimate", "estimate"), stat_label = c("Survival Probability", - "Survival Probability", "Survival Probability", "Survival Probability", - "Mean", "Mean"), stat = list(0.908163265306122, 0.46938775510204, - 0.862745098039216, 0.411764705882353, c(`mean of x` = 47.010989010989), - c(`mean of x` = 47.4489795918367)), fmt_fn = list("xx.x%", - "xx.x%", "xx.x%", "xx.x%", 1L, 1L)), row.names = c(NA, -6L - ), class = c("card", "tbl_df", "tbl", "data.frame")) + # build non-standard ARDs + ard <- cards::bind_ard( + survival::survfit(survival::Surv(ttdeath, death) ~ trt, trial) |> + cardx::ard_survival_survfit(times = c(12, 24)) |> + dplyr::filter(stat_name %in% c("estimate")) |> + dplyr::mutate( + fmt_fn = list("xx.x%"), + group1_level = unlist(group1_level) |> as.character() |> as.list() + ), + cardx::ard_stats_t_test_onesample(trial, variables = age, by = trt) |> + dplyr::filter(stat_name %in% c("estimate")) + ) |> + dplyr::select(-cards::all_missing_columns()) expect_snapshot( tbl_ard_summary(ard, by = trt, statistic = ~ "{estimate}") |> From ce2c433df843c48ef22fa2e78b922976508f08de Mon Sep 17 00:00:00 2001 From: Daniel Sjoberg Date: Thu, 26 Sep 2024 08:23:26 -0700 Subject: [PATCH 5/5] Update R/tbl_ard_summary.R Co-authored-by: Davide Garolini --- R/tbl_ard_summary.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/tbl_ard_summary.R b/R/tbl_ard_summary.R index 50adeef75..73d54b7be 100644 --- a/R/tbl_ard_summary.R +++ b/R/tbl_ard_summary.R @@ -168,7 +168,7 @@ tbl_ard_summary <- function(cards, # for non-standard ARDs, fill in the missing default types for (v in setdiff(include, names(default_types))) { if (!"variable_level" %in% names(cards) || - is_empty(compact(dplyr::filter(cards, .data$variable %in%.env$v)$variable_level))) { + is_empty(compact(dplyr::filter(cards, .data$variable %in% .env$v)$variable_level))) { default_types[[v]] <- "continuous" } else default_types[[v]] <- "categorical" # styler: off