From 2ee7c1ec6df2406126a925c0a6c2336e5271ce03 Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 19:30:05 +0200 Subject: [PATCH 1/7] replace datagridcf() and deprecate tidy_marginal_means() --- DESCRIPTION | 2 +- R/marginal_tidiers.R | 15 ++++++++-- man/tidy_marginal_means.Rd | 9 ++++-- tests/testthat/test-marginal_tidiers.R | 27 ++---------------- vignettes/articles/marginal_tidiers.Rmd | 37 +++++++++++++------------ 5 files changed, 41 insertions(+), 49 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0bf770f2..13675e45 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -56,7 +56,7 @@ Suggests: lfe, lme4 (>= 1.1.28), logitr (>= 0.8.0), - marginaleffects (>= 0.10.0), + marginaleffects (>= 0.18.0), margins, MASS, mgcv, diff --git a/R/marginal_tidiers.R b/R/marginal_tidiers.R index 4017d6b0..2d664b2e 100644 --- a/R/marginal_tidiers.R +++ b/R/marginal_tidiers.R @@ -412,7 +412,10 @@ tidy_avg_comparisons <- function(x, conf.int = TRUE, conf.level = 0.95, ...) { #' Marginal Means with `marginaleffects::marginal_means()` #' -#' `r lifecycle::badge("experimental")` +#' `r lifecycle::badge("deprecated")` +#' This function is deprecated. Use instead `tidy_marginal_predictions()` with +#' the option `newdata = "marginalmeans"`. +#' #' Use `marginaleffects::marginal_means()` to estimate marginal means and #' return a tibble tidied in a way that it could be used by `broom.helpers` #' functions. See `marginaleffects::marginal_means()()` for a list of supported @@ -451,6 +454,13 @@ tidy_avg_comparisons <- function(x, conf.int = TRUE, conf.level = 0.95, ...) { #' mod2 <- lm(Petal.Length ~ poly(Petal.Width, 2) + Species, data = iris) #' tidy_marginal_means(mod2) tidy_marginal_means <- function(x, conf.int = TRUE, conf.level = 0.95, ...) { + lifecycle::deprecate_warn( + when = "1.16.0", + what = "tidy_marginal_means()", + with = "tidy_marginal_predictions()", + details = "Specify `newdata = \"marginalmeans\"`." + ) + .assert_package("marginaleffects") dots <- rlang::dots_list(...) @@ -1029,7 +1039,8 @@ tidy_marginal_contrasts <- function(x, variables_list = "auto", if (!is.null(variables$by) && is.null(dots$newdata)) { args <- variables$by args$model <- dots$model - dots$newdata <- do.call(marginaleffects::datagridcf, args) + args$grid_type <- "counterfactual" + dots$newdata <- do.call(marginaleffects::datagrid, args) } if (!is.null(variables$by) && identical(dots$newdata, "mean")) { diff --git a/man/tidy_marginal_means.Rd b/man/tidy_marginal_means.Rd index 4e3960db..54367a49 100644 --- a/man/tidy_marginal_means.Rd +++ b/man/tidy_marginal_means.Rd @@ -18,13 +18,16 @@ interval in the tidied output} \code{marginaleffects::marginal_means()}} } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +This function is deprecated. Use instead \code{tidy_marginal_predictions()} with +the option \code{newdata = "marginalmeans"}. +} +\details{ Use \code{marginaleffects::marginal_means()} to estimate marginal means and return a tibble tidied in a way that it could be used by \code{broom.helpers} functions. See \code{marginaleffects::marginal_means()()} for a list of supported models. -} -\details{ + \code{marginaleffects::marginal_means()} estimate marginal means: adjusted predictions, averaged across a grid of categorical predictors, holding other numeric predictors at their means. Please refer to the diff --git a/tests/testthat/test-marginal_tidiers.R b/tests/testthat/test-marginal_tidiers.R index 700ab8f5..eff6fb0b 100644 --- a/tests/testthat/test-marginal_tidiers.R +++ b/tests/testthat/test-marginal_tidiers.R @@ -347,31 +347,8 @@ test_that("tidy_marginal_means()", { skip_if_not_installed("marginaleffects") mod <- lm(Petal.Length ~ Petal.Width * Species + Sepal.Length, data = iris) - expect_error( - t <- tidy_marginal_means(mod), - NA - ) - expect_error( - tidy_marginal_means(mod, exponentiate = TRUE) - ) - expect_error( - res <- tidy_plus_plus(mod, tidy_fun = tidy_marginal_means), - NA - ) - expect_equal( - nrow(res), - nrow(t) - ) - expect_equal( - attr(res, "coefficients_label"), - "Marginal Means" - ) - expect_error( - tidy_plus_plus( - mod, - tidy_fun = tidy_marginal_means, - add_pairwise_contrasts = TRUE - ) + expect_deprecated( + tidy_marginal_means(mod) ) }) diff --git a/vignettes/articles/marginal_tidiers.Rmd b/vignettes/articles/marginal_tidiers.Rmd index 7b4dea23..3cb4b9f5 100644 --- a/vignettes/articles/marginal_tidiers.Rmd +++ b/vignettes/articles/marginal_tidiers.Rmd @@ -277,6 +277,7 @@ predict(mod, newdata = dB, type = "link") %>% mean() %>% b$linkinv() ``` + We can use `tidy_marginal_predictions()` to get average marginal predictions for all variables and `plot_marginal_predictions()` for a visual representation. ```{r} @@ -327,7 +328,7 @@ pred <- predictions(mod, newdata = "marginalmeans") pred ``` -As we can see, `pred` contains 8 rows, one for each combination of `trt` (2 modalities) and `stage` (4 modalities). `age` is fixed at his mean (`mean(d$age)`) as well as `marker`. +As we can see, `pred` contains 8 rows, one for each combination of `trt` (2 modalities) and `stage` (4 modalities). `age` is fixed at its mean (`mean(d$age)`) as well as `marker`. Let's compute the average predictions for each value of `stage`. @@ -343,22 +344,19 @@ We can check that we obtain the same estimates as with `emmeans::emmeans()`. emmeans::emmeans(mod, "stage", type = "response") ``` -The function `marginaleffects::marginal_means()` allows to compute directly marginal means of all categorical variables. - -```{r} -marginal_means(mod) -``` +These estimates could be computed, for each categorical variable, with `marginaleffects::prediction()` using `datagrid(grid_type = "balanced")`[^1]. -`{broom.helpers}` provides a `tidy_marginal_means()` tidier. +[^1]: The function `marginaleffects::marginalmeans()` is now deprecated. ```{r} -mod %>% - tbl_regression( - tidy_fun = tidy_marginal_means, - estimate_fun = scales::label_percent(accuracy = .1) - ) %>% - modify_column_hide("p.value") %>% - bold_labels() +predictions(mod, + by = "trt", + newdata = datagrid(grid_type = "balanced") +) +predictions(mod, + by = "stage", + newdata = datagrid(grid_type = "balanced") +) ``` Marginal means are defined only for categorical variables. However, we can define **marginal predictions at marginal means** for both continuous and categorical variables, calling `tidy_marginal_predictions()` with the option `newdata = "marginalmeans"`. For categorical variables, marginal predictions at marginal means will be equal to marginal means. @@ -578,8 +576,11 @@ In our model, we defined an interaction between `trt` and `marker`. Therefore, w avg_comparisons( mod, variables = list(marker = 1), - newdata = datagridcf(trt = unique), - by = "trt", + newdata = datagrid( + trt = unique, + grid_type = "counterfactual" + ), + by = "trt" ) ``` @@ -709,9 +710,9 @@ mod_alt %>% ### Marginal Effects at the Mean (MEM) -For marginal effects at the mean[^1], simple use `newdata = "mean"`. +For marginal effects at the mean[^2], simple use `newdata = "mean"`. -[^1]: More precisely, `marginaleffects::marginaleffects()` use the mean of continuous variables and the mode of categorical variables. +[^2]: More precisely, `marginaleffects::marginaleffects()` use the mean of continuous variables and the mode of categorical variables. ```{r} mod %>% From 5376e2efc6dd5c451b66af7fd1a6bd8713978fd3 Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 19:34:41 +0200 Subject: [PATCH 2/7] NEWS update --- NEWS.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NEWS.md b/NEWS.md index adc179be..27e957bd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,17 @@ - `biglmm::bigglm()` not supported anymore as `bigglmm` has been removed from CRAN + +**Deprecated functions** + +- `tidy_marginal_means()` is now deprecated, following deprecation of + `marginaleffects::marginal_means()`. Use instead `tidy_marginal_predictions()` + with the option `newdata = "marginalmeans"`. + +**Fixes** + +- `tidy_marginal_predictions()` has been updated to avoid the use of the + deprecated function `marginaleffects::datagridcf()` (#256) # broom.helpers 1.15.0 From 59507d7f38dbbf6aa60caf82fbb6bbad89ebaf2b Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 19:37:31 +0200 Subject: [PATCH 3/7] lme4 requires Matrix which requires recent version of R --- .github/workflows/R-CMD-historic-R-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-historic-R-check.yaml b/.github/workflows/R-CMD-historic-R-check.yaml index ff24d974..179c3a10 100644 --- a/.github/workflows/R-CMD-historic-R-check.yaml +++ b/.github/workflows/R-CMD-historic-R-check.yaml @@ -38,7 +38,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::rcmdcheck, emmeans=?ignore-before-r=4.3.0, gam=?ignore-before-r=4.0.0, rstan=?ignore-before-r=4.0.0, multgee=?ignore-before-r=4.0.0, VGAM=?ignore-before-r=4.0.0, glmmTMB=?ignore, effects=?ignore-before-r=4.3.0, survey=?ignore-before-r=4.1.0 + extra-packages: any::rcmdcheck, emmeans=?ignore-before-r=4.3.0, gam=?ignore-before-r=4.0.0, rstan=?ignore-before-r=4.0.0, multgee=?ignore-before-r=4.0.0, VGAM=?ignore-before-r=4.0.0, glmmTMB=?ignore, effects=?ignore-before-r=4.3.0, survey=?ignore-before-r=4.1.0, lme4=?ignore-before-r=4.4.0 needs: check - uses: r-lib/actions/check-r-package@v2 From be7b451a23350e21b09e39fc3eceff31c4a5ef88 Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 20:26:54 +0200 Subject: [PATCH 4/7] tests not relevant anymore --- tests/testthat/test-marginal_tidiers.R | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/tests/testthat/test-marginal_tidiers.R b/tests/testthat/test-marginal_tidiers.R index eff6fb0b..479482fc 100644 --- a/tests/testthat/test-marginal_tidiers.R +++ b/tests/testthat/test-marginal_tidiers.R @@ -458,12 +458,6 @@ test_that("Marginal tidiers works with nnet::multinom() models", { ) expect_true("y.level" %in% names(res)) - expect_error( - res <- tidy_marginal_means(mod), - NA - ) - expect_true("y.level" %in% names(res)) - expect_error( res <- tidy_marginal_predictions(mod), NA @@ -524,12 +518,6 @@ test_that("Marginal tidiers works with MASS::polr() models", { ) expect_true("y.level" %in% names(res)) - expect_error( - suppressMessages(res <- tidy_marginal_means(mod)), - NA - ) - expect_true("y.level" %in% names(res)) - expect_error( suppressMessages(res <- tidy_marginal_predictions(mod)), NA @@ -588,12 +576,6 @@ test_that("Marginal tidiers works with ordinal::clm() models", { ) expect_true("y.level" %in% names(res)) - expect_error( - res <- tidy_marginal_means(mod), - NA - ) - expect_true("y.level" %in% names(res)) - expect_error( res <- tidy_marginal_predictions(mod), NA From b38a4ac2103f395fcd80552091ee85b23de9c4ca Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 20:27:47 +0200 Subject: [PATCH 5/7] mention lifecycle --- tests/testthat/test-marginal_tidiers.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-marginal_tidiers.R b/tests/testthat/test-marginal_tidiers.R index 479482fc..4d3f480d 100644 --- a/tests/testthat/test-marginal_tidiers.R +++ b/tests/testthat/test-marginal_tidiers.R @@ -347,7 +347,7 @@ test_that("tidy_marginal_means()", { skip_if_not_installed("marginaleffects") mod <- lm(Petal.Length ~ Petal.Width * Species + Sepal.Length, data = iris) - expect_deprecated( + lifecycle::expect_deprecated( tidy_marginal_means(mod) ) }) From ffdf045e5d0a407bbe8ba43a148ce31703005643 Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 20:32:17 +0200 Subject: [PATCH 6/7] lint --- tests/testthat/test-attach_and_detach.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat/test-attach_and_detach.R b/tests/testthat/test-attach_and_detach.R index 1aeadbfa..7bb3f831 100644 --- a/tests/testthat/test-attach_and_detach.R +++ b/tests/testthat/test-attach_and_detach.R @@ -33,4 +33,3 @@ test_that("tidy_and_attach() handles models without exponentiate arguments", { expect_error(mod %>% tidy_and_attach(exponentiate = TRUE)) expect_error(mod %>% tidy_and_attach(), NA) }) - From b7fe7c7d36ecae38c8ca979b6bd3cf55ecc94a82 Mon Sep 17 00:00:00 2001 From: Joseph Larmarange Date: Mon, 1 Jul 2024 20:33:26 +0200 Subject: [PATCH 7/7] still issues with Matrix --- .github/workflows/R-CMD-historic-R-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-historic-R-check.yaml b/.github/workflows/R-CMD-historic-R-check.yaml index 179c3a10..e27fdd90 100644 --- a/.github/workflows/R-CMD-historic-R-check.yaml +++ b/.github/workflows/R-CMD-historic-R-check.yaml @@ -38,7 +38,7 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::rcmdcheck, emmeans=?ignore-before-r=4.3.0, gam=?ignore-before-r=4.0.0, rstan=?ignore-before-r=4.0.0, multgee=?ignore-before-r=4.0.0, VGAM=?ignore-before-r=4.0.0, glmmTMB=?ignore, effects=?ignore-before-r=4.3.0, survey=?ignore-before-r=4.1.0, lme4=?ignore-before-r=4.4.0 + extra-packages: any::rcmdcheck, emmeans=?ignore-before-r=4.3.0, gam=?ignore-before-r=4.0.0, rstan=?ignore-before-r=4.0.0, multgee=?ignore-before-r=4.0.0, VGAM=?ignore-before-r=4.0.0, glmmTMB=?ignore, effects=?ignore-before-r=4.3.0, survey=?ignore-before-r=4.1.0, lme4=?ignore-before-r=4.4.0, rstanarm=?ignore-before-r=4.4.0, Matrix=?ignore-before-r=4.4.0 needs: check - uses: r-lib/actions/check-r-package@v2