diff --git a/DESCRIPTION b/DESCRIPTION index de002975ec..8515c29a4c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: gtsummary Title: Presentation-Ready Data Summary and Analytic Result Tables -Version: 1.7.2.9000 +Version: 1.7.2.9001 Authors@R: c(person(given = "Daniel D.", family = "Sjoberg", @@ -75,12 +75,12 @@ Depends: R (>= 3.4) Imports: broom (>= 1.0.1), - broom.helpers (>= 1.13.0), + broom.helpers (>= 1.14.0), cli (>= 3.1.1), dplyr (>= 1.1.1), forcats (>= 1.0.0), glue (>= 1.6.2), - gt (>= 0.9.0), + gt (>= 0.10.0), knitr (>= 1.37), lifecycle (>= 1.0.1), purrr (>= 1.0.1), diff --git a/NEWS.md b/NEWS.md index 0517b12007..81ccd0c0f5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # gtsummary (development version) +* Fix in `add_difference()` for pair t-tests. Previously, the sign of the reported difference depended on which group appeared first in the source data. Function has been updated to consistently report the difference as the first group mean minus the second group mean. (#1557) + # gtsummary 1.7.2 * Removed messaging about the former auto-removal of the `tbl_summary(group)` variable from the table: a change that occurred 3+ years ago in gtsummary v1.3.1 diff --git a/R/utils-add_p_tests.R b/R/utils-add_p_tests.R index 3da3576d8d..dec5734a6f 100644 --- a/R/utils-add_p_tests.R +++ b/R/utils-add_p_tests.R @@ -141,7 +141,7 @@ add_p_tbl_summary_paired.t.test <- function(data, variable, by, group, # reshaping data data_wide <- - tidyr::pivot_wider(data, + tidyr::pivot_wider(dplyr::arrange(data, .data[[by]]), id_cols = all_of(group), names_from = all_of(by), values_from = all_of(variable) @@ -245,7 +245,7 @@ add_p_tbl_summary_paired.wilcox.test <- function(data, variable, by, group, # reshaping data data_wide <- - tidyr::pivot_wider(data, + tidyr::pivot_wider(dplyr::arrange(data, .data[[by]]), id_cols = all_of(group), names_from = all_of(by), values_from = all_of(variable) diff --git a/tests/testthat/_snaps/add_difference.md b/tests/testthat/_snaps/add_difference.md index 92c8fe76b2..05412fc153 100644 --- a/tests/testthat/_snaps/add_difference.md +++ b/tests/testthat/_snaps/add_difference.md @@ -135,3 +135,33 @@ 1 -0.42 -4.5, 3.7 0.8 2 -4.7% -18%, 8.4% 0.5 +# ordering in add_difference() with paired tests + + Code + mtcars %>% mutate(.by = am, id = row_number(), am = factor(am, levels = c(0, 1))) %>% + tbl_summary(by = am, include = mpg) %>% add_difference(test = ~ + "paired.t.test", group = id) %>% as_kable() + Message + Note for variable 'mpg': Some observations included in the calculation of summary statistics were omitted from the p-value calculation due to unbalanced missingness within group. + Output + + + |**Characteristic** | **0**, N = 19 | **1**, N = 13 | **Difference** | **95% CI** | **p-value** | + |:------------------|:-----------------:|:-----------------:|:--------------:|:----------:|:-----------:| + |mpg | 17.3 (15.0, 19.2) | 22.8 (21.0, 30.4) | -7.0 | -10, -3.6 | <0.001 | + +--- + + Code + mtcars %>% mutate(.by = am, id = row_number(), am = factor(am, levels = c(1, 0))) %>% + tbl_summary(by = am, include = mpg) %>% add_difference(test = ~ + "paired.t.test", group = id) %>% as_kable() + Message + Note for variable 'mpg': Some observations included in the calculation of summary statistics were omitted from the p-value calculation due to unbalanced missingness within group. + Output + + + |**Characteristic** | **1**, N = 13 | **0**, N = 19 | **Difference** | **95% CI** | **p-value** | + |:------------------|:-----------------:|:-----------------:|:--------------:|:----------:|:-----------:| + |mpg | 22.8 (21.0, 30.4) | 17.3 (15.0, 19.2) | 7.0 | 3.6, 10 | <0.001 | + diff --git a/tests/testthat/_snaps/as_gt.md b/tests/testthat/_snaps/as_gt.md index 6a7911958f..a3cd9f7f4f 100644 --- a/tests/testthat/_snaps/as_gt.md +++ b/tests/testthat/_snaps/as_gt.md @@ -15,7 +15,7 @@ Chemotherapy Treatment - +
    Drug A 98 (49%)     Drug B @@ -29,7 +29,7 @@     Unknown 10 T Stage - +
    T1 53 (27%)     T2 @@ -39,7 +39,7 @@     T4 50 (25%) Grade - +
    I 68 (34%)     II @@ -81,7 +81,7 @@ Chemotherapy Treatment - +
    Drug A 98 (49%)     Drug B @@ -128,10 +128,10 @@ Chemotherapy Treatment - - - - +
+
+
+
    Drug A 35 32 @@ -206,16 +206,16 @@ Chemotherapy Treatment 189 - - - +
+
+
    Drug A - +
— — - +
    Drug B - +
0.44 -3.7, 4.6 0.8 @@ -226,46 +226,46 @@ >0.9 T Stage 189 - - - +
+
+
    T1 - +
— — - +
    T2 - +
1.3 -4.2, 6.9 0.6     T3 - +
2.6 -3.3, 8.6 0.4     T4 - +
-2.0 -7.8, 3.8 0.5 Grade 189 - - - +
+
+
    I - +
— — - +
    II - +
1.4 -3.6, 6.4 0.6     III - +
2.0 -3.1, 7.0 0.4 @@ -312,8 +312,8 @@ Chemotherapy Treatment - - +
+
    Drug A 91% (85%, 97%) 47% (38%, 58%) diff --git a/tests/testthat/test-add_difference.R b/tests/testthat/test-add_difference.R index 32ad609ace..6d2c01af1a 100644 --- a/tests/testthat/test-add_difference.R +++ b/tests/testthat/test-add_difference.R @@ -342,3 +342,35 @@ test_that("add_difference() with emmeans()", { NA ) }) + + +test_that("ordering in add_difference() with paired tests", { + expect_snapshot( + mtcars %>% + mutate( + .by = am, + id = row_number(), + am = factor(am, levels = c(0, 1)) + ) %>% + tbl_summary( + by = am, + include = mpg + ) %>% + add_difference(test = ~"paired.t.test", group = id) %>% + as_kable() + ) + expect_snapshot( + mtcars %>% + mutate( + .by = am, + id = row_number(), + am = factor(am, levels = c(1, 0)) + ) %>% + tbl_summary( + by = am, + include = mpg + ) %>% + add_difference(test = ~"paired.t.test", group = id) %>% + as_kable() + ) +}) diff --git a/tests/testthat/test-vetted_models-clogit.R b/tests/testthat/test-vetted_models-clogit.R index 59599d7f11..9698292252 100644 --- a/tests/testthat/test-vetted_models-clogit.R +++ b/tests/testthat/test-vetted_models-clogit.R @@ -25,7 +25,6 @@ skip_on_cran() skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) library(survival) # clogit() --------------------------------------------------------------------- diff --git a/tests/testthat/test-vetted_models-coxph.R b/tests/testthat/test-vetted_models-coxph.R index dc4fdd2c19..181bae7d25 100644 --- a/tests/testthat/test-vetted_models-coxph.R +++ b/tests/testthat/test-vetted_models-coxph.R @@ -25,14 +25,12 @@ skip_on_cran() skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) -library(survival) # coxph() ---------------------------------------------------------------------- test_that("vetted_models coxph()", { # building models to check - mod_coxph_lin <- coxph(Surv(ttdeath, death) ~ age + trt + grade, data = trial) - mod_coxph_int <- coxph(Surv(ttdeath, death) ~ age + trt * grade, data = trial) + mod_coxph_lin <- survival::coxph(survival::Surv(ttdeath, death) ~ age + trt + grade, data = trial) + mod_coxph_int <- survival::coxph(survival::Surv(ttdeath, death) ~ age + trt * grade, data = trial) # 1. Runs as expected with standard use # - without errors, warnings, messages expect_error( @@ -157,8 +155,8 @@ test_that("vetted_models coxph()", { expect_error( trial %>% tbl_uvregression( - y = Surv(ttdeath, death), - method = coxph + y = survival::Surv(ttdeath, death), + method = survival::coxph ) %>% add_global_p() %>% add_q(), @@ -167,8 +165,8 @@ test_that("vetted_models coxph()", { expect_warning( trial %>% tbl_uvregression( - y = Surv(ttdeath, death), - method = coxph + y = survival::Surv(ttdeath, death), + method = survival::coxph ) %>% add_nevent() %>% add_global_p() %>% diff --git a/tests/testthat/test-vetted_models-geeglm.R b/tests/testthat/test-vetted_models-geeglm.R index 4cb292d084..5ddcb42bed 100644 --- a/tests/testthat/test-vetted_models-geeglm.R +++ b/tests/testthat/test-vetted_models-geeglm.R @@ -26,7 +26,6 @@ skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("geepack", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) # geeglm() -------------------------------------------------------------------- test_that("vetted_models geeglm()", { diff --git a/tests/testthat/test-vetted_models-glm.R b/tests/testthat/test-vetted_models-glm.R index 24e6845ff6..2129a0d8d6 100644 --- a/tests/testthat/test-vetted_models-glm.R +++ b/tests/testthat/test-vetted_models-glm.R @@ -26,7 +26,6 @@ skip_on_cran() skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) # glm() ------------------------------------------------------------------------ test_that("vetted_models glm()", { diff --git a/tests/testthat/test-vetted_models-glmer.R b/tests/testthat/test-vetted_models-glmer.R index c6d2fdb290..e1d8f8d20c 100644 --- a/tests/testthat/test-vetted_models-glmer.R +++ b/tests/testthat/test-vetted_models-glmer.R @@ -26,7 +26,6 @@ skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("lme4", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) # glmer() -------------------------------------------------------------------- test_that("vetted_models glmer()", { diff --git a/tests/testthat/test-vetted_models-lm.R b/tests/testthat/test-vetted_models-lm.R index c4c911af0d..c65c8b81be 100644 --- a/tests/testthat/test-vetted_models-lm.R +++ b/tests/testthat/test-vetted_models-lm.R @@ -25,7 +25,6 @@ skip_on_cran() testthat::skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) # lm() ------------------------------------------------------------------------ test_that("vetted_models lm()", { diff --git a/tests/testthat/test-vetted_models-lmer.R b/tests/testthat/test-vetted_models-lmer.R index 6cbaebaf2a..84dd6fec29 100644 --- a/tests/testthat/test-vetted_models-lmer.R +++ b/tests/testthat/test-vetted_models-lmer.R @@ -26,7 +26,6 @@ skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("lme4", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) # lmer() ----------------------------------------------------------------------- test_that("vetted_models lmer()", { diff --git a/tests/testthat/test-vetted_models-survreg.R b/tests/testthat/test-vetted_models-survreg.R index 869957defb..7eaa3f60be 100644 --- a/tests/testthat/test-vetted_models-survreg.R +++ b/tests/testthat/test-vetted_models-survreg.R @@ -35,15 +35,13 @@ skip_if(!isTRUE(as.logical(Sys.getenv("CI")))) skip_if_not(broom.helpers::.assert_package("car", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("lme4", pkg_search = "gtsummary", boolean = TRUE)) skip_if_not(broom.helpers::.assert_package("survival", pkg_search = "gtsummary", boolean = TRUE)) -library(dplyr) -library(survival) # survreg() -------------------------------------------------------------------- test_that("vetted_models survreg()", { # building models to check - mod_survreg_lin <- survreg(Surv(ttdeath, death) ~ age + trt + grade, data = trial) - mod_survreg_int <- survreg(Surv(ttdeath, death) ~ age + trt * grade, data = trial) + mod_survreg_lin <- survival::survreg(survival::Surv(ttdeath, death) ~ age + trt + grade, data = trial) + mod_survreg_int <- survival::survreg(survival::Surv(ttdeath, death) ~ age + trt * grade, data = trial) # 1. Runs as expected with standard use # - without errors, warnings, messages expect_error( @@ -82,15 +80,15 @@ test_that("vetted_models survreg()", { # - labels are correct expect_equal( tbl_survreg_lin$table_body %>% - filter(row_type == "label") %>% - pull(label), + dplyr::filter(row_type == "label") %>% + dplyr::pull(label), c("Age", "Chemotherapy Treatment", "Grade"), ignore_attr = TRUE ) expect_equal( tbl_survreg_int$table_body %>% - filter(row_type == "label") %>% - pull(label), + dplyr::filter(row_type == "label") %>% + dplyr::pull(label), c("Age", "Chemotherapy Treatment", "Grade", "Chemotherapy Treatment * Grade"), ignore_attr = TRUE ) @@ -99,8 +97,8 @@ test_that("vetted_models survreg()", { # - interaction labels are correct expect_equal( tbl_survreg_int$table_body %>% - filter(var_type == "interaction") %>% - pull(label), + dplyr::filter(var_type == "interaction") %>% + dplyr::pull(label), c("Chemotherapy Treatment * Grade", "Drug B * II", "Drug B * III"), ignore_attr = TRUE ) @@ -127,7 +125,7 @@ test_that("vetted_models survreg()", { # - numbers in table are correct expect_equal( tbl_survreg_lin2$table_body %>% - pull(p.value) %>% + dplyr::pull(p.value) %>% na.omit() %>% as.vector(), car::Anova(mod_survreg_lin, type = "III") %>% @@ -137,16 +135,16 @@ test_that("vetted_models survreg()", { ) expect_equal( tbl_survreg_int2$table_body %>% - pull(p.value) %>% + dplyr::pull(p.value) %>% na.omit() %>% as.vector(), car::Anova(mod_survreg_int, type = "III") %>% as.data.frame() %>% - pull(`Pr(>Chisq)`), + dplyr::pull(`Pr(>Chisq)`), ignore_attr = TRUE ) expect_equal( - tbl_survreg_lin3$table_body %>% filter(variable == "trt") %>% pull(p.value), + tbl_survreg_lin3$table_body %>% dplyr::filter(variable == "trt") %>% pull(p.value), car::Anova(mod_survreg_lin, type = "III") %>% as.data.frame() %>% tibble::rownames_to_column() %>% @@ -160,8 +158,8 @@ test_that("vetted_models survreg()", { expect_error( trial %>% tbl_uvregression( - y = Surv(ttdeath, death), - method = survreg + y = survival::Surv(ttdeath, death), + method = survival::survreg ) %>% add_global_p() %>% add_q(),