From 8d44cd8e804bb27b704d4eb91cb70be5bad24372 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 21 Aug 2024 20:17:07 +0200 Subject: [PATCH 1/6] model_paramaters with exponentiate = TRUE not working with bootstrapped object from bootstrap_model Fixes #1004 --- R/methods_base.R | 8 ++++++-- R/methods_posterior.R | 4 ++++ man/model_parameters.stanreg.Rd | 35 ++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/R/methods_base.R b/R/methods_base.R index 955660264..40afadda8 100644 --- a/R/methods_base.R +++ b/R/methods_base.R @@ -1,9 +1,13 @@ #' @rdname model_parameters.stanreg #' @export -model_parameters.data.frame <- function(model, as_draws = FALSE, verbose = TRUE, ...) { +model_parameters.data.frame <- function(model, + as_draws = FALSE, + exponentiate = FALSE, + verbose = TRUE, + ...) { # treat data frame as bootstraps/posteriors? if (isTRUE(as_draws)) { - return(model_parameters.draws(model, verbose = verbose, ...)) + return(model_parameters.draws(model, exponentiate = exponentiate, verbose = verbose, ...)) } if (isTRUE(verbose)) { insight::format_warning( diff --git a/R/methods_posterior.R b/R/methods_posterior.R index 3b58b59bf..24e096659 100644 --- a/R/methods_posterior.R +++ b/R/methods_posterior.R @@ -8,6 +8,7 @@ model_parameters.draws <- function(model, test = "pd", rope_range = "default", rope_ci = 0.95, + exponentiate = FALSE, keep = NULL, drop = NULL, verbose = TRUE, @@ -33,6 +34,9 @@ model_parameters.draws <- function(model, ... ) + # exponentiate coefficients and SE/CI, if requested + params <- .exponentiate_parameters(params) + attr(params, "ci") <- ci attr(params, "object_name") <- insight::safe_deparse_symbol(substitute(model)) class(params) <- c("parameters_model", "see_parameters_model", class(params)) diff --git a/man/model_parameters.stanreg.Rd b/man/model_parameters.stanreg.Rd index 3980d2292..ef2f3f623 100644 --- a/man/model_parameters.stanreg.Rd +++ b/man/model_parameters.stanreg.Rd @@ -27,7 +27,13 @@ ... ) -\method{model_parameters}{data.frame}(model, as_draws = FALSE, verbose = TRUE, ...) +\method{model_parameters}{data.frame}( + model, + as_draws = FALSE, + exponentiate = FALSE, + verbose = TRUE, + ... +) \method{model_parameters}{brmsfit}( model, @@ -61,6 +67,7 @@ test = "pd", rope_range = "default", rope_ci = 0.95, + exponentiate = FALSE, keep = NULL, drop = NULL, verbose = TRUE, @@ -171,6 +178,19 @@ the data frame is treated as posterior samples and handled similar to Bayesian models. All arguments in \code{...} are passed to \code{model_parameters.draws()}.} +\item{exponentiate}{Logical, indicating whether or not to exponentiate the +coefficients (and related confidence intervals). This is typical for +logistic regression, or more generally speaking, for models with log or +logit links. It is also recommended to use \code{exponentiate = TRUE} for models +with log-transformed response values. \strong{Note:} Delta-method standard +errors are also computed (by multiplying the standard errors by the +transformed coefficients). This is to mimic behaviour of other software +packages, such as Stata, but these standard errors poorly estimate +uncertainty for the transformed coefficient. The transformed confidence +interval more clearly captures this uncertainty. For \code{compare_parameters()}, +\code{exponentiate = "nongaussian"} will only exponentiate coefficients from +non-Gaussian families.} + \item{effects}{Should results for fixed effects, random effects or both be returned? Only applies to mixed models. May be abbreviated.} @@ -188,19 +208,6 @@ argument - but no auxiliary parameters). For \code{component = "distributional"} (or \code{"auxiliary"}), components like \code{sigma}, \code{dispersion}, or \code{beta} (and other auxiliary parameters) are returned.} -\item{exponentiate}{Logical, indicating whether or not to exponentiate the -coefficients (and related confidence intervals). This is typical for -logistic regression, or more generally speaking, for models with log or -logit links. It is also recommended to use \code{exponentiate = TRUE} for models -with log-transformed response values. \strong{Note:} Delta-method standard -errors are also computed (by multiplying the standard errors by the -transformed coefficients). This is to mimic behaviour of other software -packages, such as Stata, but these standard errors poorly estimate -uncertainty for the transformed coefficient. The transformed confidence -interval more clearly captures this uncertainty. For \code{compare_parameters()}, -\code{exponentiate = "nongaussian"} will only exponentiate coefficients from -non-Gaussian families.} - \item{standardize}{The method used for standardizing the parameters. Can be \code{NULL} (default; no standardization), \code{"refit"} (for re-fitting the model on standardized data) or one of \code{"basic"}, \code{"posthoc"}, \code{"smart"}, From 1a9b6e613532c88141f58020d991c7b7a0a30c8f Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 21 Aug 2024 20:19:02 +0200 Subject: [PATCH 2/6] desc, news --- DESCRIPTION | 2 +- NEWS.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 68909918d..118c78e16 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: parameters Title: Processing of Model Parameters -Version: 0.22.1.7 +Version: 0.22.1.8 Authors@R: c(person(given = "Daniel", family = "Lüdecke", diff --git a/NEWS.md b/NEWS.md index b584b4f12..554b5dc2f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,9 @@ * Methods for `degrees_of_freedom()` have been removed. `degrees_of_freedom()` now calls `insight::get_df()`. +* `model_parameters()` for data frames and `draws` objects from package + *posterior* also gets an `exponentiate` argument. + ## Bug fixes * Fixed issue with warning for spuriously high coefficients for Stan-models From 2d73a29865c3823bd7332d94721af749151e4955 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 21 Aug 2024 20:28:28 +0100 Subject: [PATCH 3/6] Update methods_posterior.R --- R/methods_posterior.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/methods_posterior.R b/R/methods_posterior.R index 24e096659..a79e9bb08 100644 --- a/R/methods_posterior.R +++ b/R/methods_posterior.R @@ -35,7 +35,7 @@ model_parameters.draws <- function(model, ) # exponentiate coefficients and SE/CI, if requested - params <- .exponentiate_parameters(params) + params <- .exponentiate_parameters(params, exponentiate = exponentiate) attr(params, "ci") <- ci attr(params, "object_name") <- insight::safe_deparse_symbol(substitute(model)) From 7022570e250b034fb482210018b43adbc8a54d71 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 21 Aug 2024 23:56:00 +0200 Subject: [PATCH 4/6] lintr --- R/methods_base.R | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/R/methods_base.R b/R/methods_base.R index 40afadda8..c83e2e07d 100644 --- a/R/methods_base.R +++ b/R/methods_base.R @@ -59,10 +59,8 @@ standard_error.list <- function(model, verbose = TRUE, ...) { model <- model$gam class(model) <- c("gam", "lm", "glm") standard_error(model) - } else { - if (isTRUE(verbose)) { - insight::print_color("\nCould not extract standard errors from model object.\n", "red") - } + } else if (isTRUE(verbose)) { + insight::print_color("\nCould not extract standard errors from model object.\n", "red") } } @@ -140,10 +138,10 @@ p_value.numeric <- function(model, null = 0, ...) { #' @export p_value.data.frame <- function(model, ...) { - data <- model[vapply(model, is.numeric, TRUE)] + model_data <- model[vapply(model, is.numeric, TRUE)] .data_frame( - Parameter = names(data), - p = vapply(data, p_value, 1) + Parameter = names(model_data), + p = vapply(model_data, p_value, 1) ) } @@ -154,9 +152,7 @@ p_value.list <- function(model, method = NULL, verbose = TRUE, ...) { model <- model$gam class(model) <- c("gam", "lm", "glm") p_value(model, method = method) - } else { - if (isTRUE(verbose)) { - insight::format_warning("Could not extract p-values from model object.") - } + } else if (isTRUE(verbose)) { + insight::format_warning("Could not extract p-values from model object.") } } From 205bb09d59ed3eb24a8c8dba8bd47eaca293ef20 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 21 Aug 2024 23:57:10 +0200 Subject: [PATCH 5/6] lintr --- R/methods_base.R | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/R/methods_base.R b/R/methods_base.R index c83e2e07d..08236bab4 100644 --- a/R/methods_base.R +++ b/R/methods_base.R @@ -26,14 +26,13 @@ model_parameters.data.frame <- function(model, #' @rdname standard_error #' @export standard_error.factor <- function(model, force = FALSE, verbose = TRUE, ...) { - if (force) { - standard_error(as.numeric(model), ...) - } else { + if (!force) { if (verbose) { insight::format_warning("Can't compute standard error of non-numeric variables.") } return(NA) } + standard_error(as.numeric(model), ...) } From fe8c1f7139b713496d347f494ba677c13fb49f87 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 22 Aug 2024 12:24:37 +0200 Subject: [PATCH 6/6] add test --- tests/testthat/test-base.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testthat/test-base.R b/tests/testthat/test-base.R index a8760d9a6..6f9e6cd87 100644 --- a/tests/testthat/test-base.R +++ b/tests/testthat/test-base.R @@ -11,6 +11,12 @@ test_that("model_parameters.data.frame as draws", { expect_identical(colnames(mp), c("Parameter", "Median", "CI_low", "CI_high", "pd")) }) +test_that("model_parameters.data.frame as draws, exponentiate", { + data(iris) + mp <- suppressWarnings(model_parameters(iris[1:4], as_draws = TRUE, exponentiate = TRUE)) + expect_equal(mp$Median, c(330.29956, 20.08554, 77.47846, 3.6693), tolerance = 1e-2, ignore_attr = TRUE) +}) + # require model input test_that("model_parameters", { expect_error(model_parameters())