diff --git a/DESCRIPTION b/DESCRIPTION index cba26e65..0d40fd3a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: modelbased Title: Estimation of Model-Based Predictions, Contrasts and Means -Version: 0.10.0.31 +Version: 0.10.0.32 Authors@R: c(person(given = "Dominique", family = "Makowski", diff --git a/R/clean_names.R b/R/clean_names.R index 067d338c..f74e877f 100644 --- a/R/clean_names.R +++ b/R/clean_names.R @@ -28,13 +28,7 @@ if (length(vars) == 1) { if (type == "contrast") { - if (minfo$is_logit && predict == "response") { - names(means)[names(means) == vars] <- "Odds_ratio" - } else if (minfo$is_poisson && predict == "response") { - names(means)[names(means) == vars] <- "Ratio" - } else { - names(means)[names(means) == vars] <- "Difference" - } + names(means)[names(means) == vars] <- "Difference" } else if (type == "mean") { if (minfo$is_logit && predict == "response") { names(means)[names(means) == vars] <- "Probability" diff --git a/R/estimate_contrast_methods.R b/R/estimate_contrast_methods.R index 26f4eb14..a05f0a33 100644 --- a/R/estimate_contrast_methods.R +++ b/R/estimate_contrast_methods.R @@ -31,7 +31,11 @@ estimate_contrasts.estimate_predicted <- function(model, minfo <- insight::model_info(model, response = 1) # model df - dof <- insight::get_df(model, type = "wald", verbose = FALSE) + if (minfo$is_bayesian) { + dof <- Inf + } else { + dof <- insight::get_df(model, type = "wald", verbose = FALSE) + } crit_factor <- (1 + ci) / 2 ## TODO: For Bayesian models, we always use the returned standard errors diff --git a/R/get_emcontrasts.R b/R/get_emcontrasts.R index 223ea89a..a41ab5f6 100644 --- a/R/get_emcontrasts.R +++ b/R/get_emcontrasts.R @@ -41,6 +41,22 @@ get_emcontrasts <- function(model, # extract first focal term first_focal <- my_args$contrast[1] + # setup arguments + fun_args <- list(model) + + # handle distributional parameters + if (predict %in% .brms_aux_elements(model) && inherits(model, "brmsfit")) { + dpars <- TRUE + fun_args$dpar <- predict + } else { + dpars <- FALSE + fun_args$type <- predict + } + + # add dots + dots <- list(...) + fun_args <- insight::compact_list(c(fun_args, dots)) + # if first focal term is numeric, we contrast slopes if (is.numeric(model_data[[first_focal]]) && !first_focal %in% on_the_fly_factors && @@ -51,23 +67,13 @@ get_emcontrasts <- function(model, insight::format_error("Please specify the `by` argument to calculate contrasts of slopes.") # nolint } # Run emmeans - estimated <- suppressMessages(emmeans::emtrends( - model, - specs = my_args$by, - var = my_args$contrast, - type = predict, - ... - )) + fun_args <- c(fun_args, list(specs = my_args$by, var = my_args$contrast)) + estimated <- suppressMessages(do.call(emmeans::emtrends, fun_args)) emm_by <- NULL } else { # Run emmeans - estimated <- suppressMessages(emmeans::emmeans( - model, - specs = my_args$emmeans_specs, - at = my_args$emmeans_at, - type = predict, - ... - )) + fun_args <- c(fun_args, list(specs = my_args$emmeans_specs, at = my_args$emmeans_at)) + estimated <- suppressMessages(do.call(emmeans::emmeans, fun_args)) # Find by variables emm_by <- my_args$emmeans_specs[!my_args$emmeans_specs %in% my_args$contrast] if (length(emm_by) == 0) { @@ -76,7 +82,7 @@ get_emcontrasts <- function(model, } # If means are on the response scale (e.g., probabilities), need to regrid - if (predict == "response") { + if (predict == "response" || dpars) { estimated <- emmeans::regrid(estimated) } diff --git a/R/get_emmeans.R b/R/get_emmeans.R index 4bdefd74..8de4c8de 100644 --- a/R/get_emmeans.R +++ b/R/get_emmeans.R @@ -58,8 +58,10 @@ get_emmeans <- function(model, # handle distributional parameters if (predict %in% .brms_aux_elements(model) && inherits(model, "brmsfit")) { + dpars <- TRUE fun_args$dpar <- predict } else { + dpars <- FALSE fun_args$type <- predict } @@ -70,6 +72,11 @@ get_emmeans <- function(model, # Run emmeans estimated <- suppressMessages(suppressWarnings(do.call(emmeans::emmeans, fun_args))) + # backtransform to response scale for dpars + if (dpars) { + estimated <- emmeans::regrid(estimated) + } + # Special behaviour for transformations #138 (see below) if ("retransform" %in% names(my_args) && length(my_args$retransform) > 0) { for (var in names(my_args$retransform)) { diff --git a/R/get_marginalmeans.R b/R/get_marginalmeans.R index caa18f41..c32db2f6 100644 --- a/R/get_marginalmeans.R +++ b/R/get_marginalmeans.R @@ -131,7 +131,7 @@ get_marginalmeans <- function(model, dots[c("by", "conf_level", "type", "digits", "bias_correction", "sigma", "offset")] <- NULL # model df - can be passed via `...` - if (is.null(dots$df)) { + if (is.null(dots$df) && !model_info$is_bayesian) { dots$df <- insight::get_df(model, type = "wald", verbose = FALSE) } @@ -225,7 +225,7 @@ get_marginalmeans <- function(model, # just need to add "hypothesis" argument means <- .call_marginaleffects(fun_args) - # Fifth step: post-processin marginal means---------------------------------- + # Fifth step: post-processing marginal means---------------------------------- # --------------------------------------------------------------------------- # filter "by" rows when we have "average" marginalization, because we don't @@ -317,7 +317,7 @@ get_marginalmeans <- function(model, msg <- c(msg, "\nIt seems that not all required levels of the focal terms are available in the provided data. If you want predictions extrapolated to a hypothetical target population, try setting `estimate=\"population\".") # nolint } # we get this error for models with complex random effects structures in glmmTMB - if (grepl("map factor length must equal", out$message, fixed = TRUE)) { + if (grepl("map factor length must equal", out$message, fixed = TRUE) || grepl("cannot allocate", out$message, fixed = TRUE)) { # nolint msg <- c( msg, paste0( @@ -335,7 +335,7 @@ get_marginalmeans <- function(model, } -# filter datagrid foe `estimate = "average"`--------------------------------- +# filter datagrid for `estimate = "average"`--------------------------------- .filter_datagrid_average <- function(means, estimate, datagrid, datagrid_info) { # filter "by" rows when we have "average" marginalization, because we don't diff --git a/R/get_marginaltrends.R b/R/get_marginaltrends.R index 0ac6a946..8c54f2be 100644 --- a/R/get_marginaltrends.R +++ b/R/get_marginaltrends.R @@ -85,7 +85,7 @@ get_marginaltrends <- function(model, } # model df - can be passed via `...` - if (is.null(dots$df)) { + if (is.null(dots$df) && !model_info$is_bayesian) { dots$df <- insight::get_df(model, type = "wald", verbose = FALSE) }