Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

estimate_means(backend = "marginaleffects") not calculating marginal means #275

Merged
merged 53 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2d202a6
`estimate_means(backend = "marginaleffects")` not calculating margina…
strengejacke Dec 13, 2024
07233e9
Merge branch 'main' into revise_marginaleffects
strengejacke Dec 13, 2024
2df97e1
remove marginal argument
DominiqueMakowski Dec 14, 2024
0103892
test against raw emmeans
DominiqueMakowski Dec 14, 2024
9417189
use default type
strengejacke Dec 15, 2024
dcea9d8
try if hypothesis can be used directly
strengejacke Dec 15, 2024
607c4a7
docs
strengejacke Dec 15, 2024
12a1d09
fix
strengejacke Dec 15, 2024
a859d13
fix
strengejacke Dec 15, 2024
11a63ea
fix
strengejacke Dec 15, 2024
2e0dcb5
fix
strengejacke Dec 15, 2024
945eaf0
fix
strengejacke Dec 15, 2024
064f374
remove browser
strengejacke Dec 15, 2024
5ad388f
fix
strengejacke Dec 15, 2024
a1a8d37
fix
strengejacke Dec 15, 2024
5e279fc
fix
strengejacke Dec 15, 2024
164bc11
fix
strengejacke Dec 15, 2024
77978b0
fix
strengejacke Dec 15, 2024
6c52e6c
fix
strengejacke Dec 15, 2024
c1f610e
fix
strengejacke Dec 15, 2024
e95a7c3
fix
strengejacke Dec 15, 2024
f9fb77f
fix
strengejacke Dec 15, 2024
f143ccc
no verbose
strengejacke Dec 15, 2024
cd94f7c
fixes
strengejacke Dec 15, 2024
12cc866
fix
strengejacke Dec 15, 2024
433548a
tests
strengejacke Dec 15, 2024
2c52934
fix
strengejacke Dec 15, 2024
d5ef200
typo
strengejacke Dec 15, 2024
f7a8529
fix
strengejacke Dec 15, 2024
1ecde16
tests
strengejacke Dec 15, 2024
23c4a16
styler
strengejacke Dec 15, 2024
ab46de3
test
strengejacke Dec 15, 2024
69083c7
lintr
strengejacke Dec 15, 2024
6d37157
tests
strengejacke Dec 15, 2024
d3ba94f
fix
strengejacke Dec 15, 2024
e7cee5f
add marginalcontrasts
strengejacke Dec 15, 2024
5c4697e
fix
strengejacke Dec 15, 2024
0bd0868
allow preserve_range to be passed to datagrid
strengejacke Dec 15, 2024
cd3682f
tests
strengejacke Dec 15, 2024
53ebb09
remove redundant test
strengejacke Dec 15, 2024
4ac3b3d
remove fixed argument
strengejacke Dec 15, 2024
d783374
export get_marginalmeans
strengejacke Dec 15, 2024
02ad2da
remove TODO
strengejacke Dec 15, 2024
7c4f4d4
test
strengejacke Dec 15, 2024
c9fdbdf
Update _pkgdown.yml
strengejacke Dec 15, 2024
3ff2770
fix warnings
strengejacke Dec 16, 2024
eddb79a
styler
strengejacke Dec 16, 2024
67978b6
fix
strengejacke Dec 16, 2024
280a588
verbose
strengejacke Dec 16, 2024
b6aa7ca
warnings
strengejacke Dec 16, 2024
1514b64
fix
strengejacke Dec 16, 2024
2478048
fix
strengejacke Dec 16, 2024
8ef636d
fix
strengejacke Dec 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,14 @@ export(find_inversions)
export(get_emcontrasts)
export(get_emmeans)
export(get_emtrends)
export(get_marginalcontrasts)
export(get_marginaleffects)
export(get_marginalmeans)
export(model_emcontrasts)
export(model_emmeans)
export(model_emtrends)
export(model_marginalcontrasts)
export(model_marginalmeans)
export(print_md)
export(reshape_grouplevel)
export(smoothing)
Expand Down
30 changes: 13 additions & 17 deletions R/estimate_contrasts.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
#' @inheritParams estimate_means
#' @inheritParams get_emcontrasts
#' @param p_adjust The p-values adjustment method for frequentist multiple
#' comparisons. Can be one of "holm" (default), "tukey", "hochberg", "hommel",
#' "bonferroni", "BH", "BY", "fdr" or "none". See the p-value adjustment
#' section in the `emmeans::test` documentation.
#' comparisons. Can be one of `"holm"` (default), `"tukey"`, `"hochberg"`,
#' `"hommel"`, `"bonferroni"`, `"BH"`, `"BY"`, `"fdr"` or `"none"`. See the
#' p-value adjustment section in the `emmeans::test` documentation.
#'
#' @inherit estimate_slopes details
#'
#' @examplesIf require("lme4", quietly = TRUE) && require("emmeans", quietly = TRUE) && require("rstanarm", quietly = TRUE)
#' @examplesIf all(insight::check_if_installed(c("lme4", "emmeans", "rstanarm"), quietly = TRUE))
#' \dontrun{
#' # Basic usage
#' model <- lm(Sepal.Width ~ Species, data = iris)
Expand All @@ -34,9 +34,6 @@
#' # Or with custom specifications
#' estimate_contrasts(model, contrast = c("Species", "Petal.Width=c(1, 2)"))
#'
#' # Can fixate the numeric at a specific value
#' estimate_contrasts(model, fixed = "Petal.Width")
#'
#' # Or modulate it
#' estimate_contrasts(model, by = "Petal.Width", length = 4)
#'
Expand All @@ -51,22 +48,24 @@
#' model <- lme4::lmer(Sepal.Width ~ Species + (1 | Petal.Length_factor), data = data)
#' estimate_contrasts(model)
#'
#' library(rstanarm)
#'
#' data <- mtcars
#' data$cyl <- as.factor(data$cyl)
#' data$am <- as.factor(data$am)
#'
#' model <- stan_glm(mpg ~ cyl * am, data = data, refresh = 0)
#' model <- rstanarm::stan_glm(mpg ~ cyl * am, data = data, refresh = 0)
#' estimate_contrasts(model)
#' estimate_contrasts(model, fixed = "am")
#' # fix `am` at value 1
#' estimate_contrasts(model, by = c("cyl", "am='1'"))
#'
#' model <- stan_glm(mpg ~ cyl * wt, data = data, refresh = 0)
#' model <- rstanarm::stan_glm(mpg ~ cyl * wt, data = data, refresh = 0)
#' estimate_contrasts(model)
#' estimate_contrasts(model, fixed = "wt")
#' estimate_contrasts(model, by = "wt", length = 4)
#'
#' model <- stan_glm(Sepal.Width ~ Species + Petal.Width + Petal.Length, data = iris, refresh = 0)
#' model <- rstanarm::stan_glm(
#' Sepal.Width ~ Species + Petal.Width + Petal.Length,
#' data = iris,
#' refresh = 0
#' )
#' estimate_contrasts(model, by = "Petal.Length", test = "bf")
#' }
#'
Expand All @@ -75,7 +74,6 @@
estimate_contrasts <- function(model,
contrast = NULL,
by = NULL,
fixed = NULL,
transform = "none",
ci = 0.95,
p_adjust = "holm",
Expand All @@ -85,7 +83,6 @@ estimate_contrasts <- function(model,
estimated <- get_emcontrasts(model,
contrast = contrast,
by = by,
fixed = fixed,
transform = transform,
method = method,
adjust = p_adjust,
Expand Down Expand Up @@ -142,7 +139,6 @@ estimate_contrasts <- function(model,
attr(out, "transform") <- transform
attr(out, "at") <- info$by
attr(out, "by") <- info$by
attr(out, "fixed") <- info$fixed
attr(out, "contrast") <- info$contrast
attr(out, "p_adjust") <- p_adjust

Expand Down
10 changes: 4 additions & 6 deletions R/estimate_means.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#' model <- lm(Petal.Length ~ Sepal.Width * Species, data = iris)
#'
#' estimate_means(model)
#' estimate_means(model, fixed = "Sepal.Width")
#' estimate_means(model, by = c("Species", "Sepal.Width"), length = 2)
#' estimate_means(model, by = "Species=c('versicolor', 'setosa')")
#' estimate_means(model, by = "Sepal.Width=c(2, 4)")
Expand All @@ -28,7 +27,7 @@
#' estimate_means(model, by = "Sepal.Width=c(2, 4)")
#'
#' # Methods that can be applied to it:
#' means <- estimate_means(model, fixed = "Sepal.Width")
#' means <- estimate_means(model, by = c("Species", "Sepal.Width=0"))
#'
#' @examplesIf require("see") && require("emmeans", quietly = TRUE)
#' plot(means) # which runs visualisation_recipe()
Expand All @@ -48,19 +47,18 @@
#' @export
estimate_means <- function(model,
by = "auto",
fixed = NULL,
transform = "response",
ci = 0.95,
backend = "emmeans",
...) {
if (backend == "emmeans") {
# Emmeans ------------------------------------------------------------------
estimated <- get_emmeans(model, by, fixed, transform = transform, ...)
estimated <- get_emmeans(model, by, transform = transform, ...)
means <- .format_emmeans_means(estimated, model, ci, transform, ...)
} else {
# Marginalmeans ------------------------------------------------------------
estimated <- .get_marginalmeans(model, by, ci = ci, ...)
means <- .format_marginaleffects_means(estimated, model, ...)
estimated <- get_marginalmeans(model, by, transform = transform, ci = ci, ...)
means <- .format_marginaleffects_means(estimated, model, transform, ...)
}


Expand Down
45 changes: 19 additions & 26 deletions R/get_emcontrasts.R
Original file line number Diff line number Diff line change
@@ -1,43 +1,38 @@
#' @rdname get_emmeans
#'
#' @param contrast A character vector indicating the name of the variable(s)
#' for which to compute the contrasts.
#' for which to compute the contrasts.
#' @param method Contrast method. See same argument in [emmeans::contrast].
#'
#' @examples
#' if (require("emmeans", quietly = TRUE)) {
#' # Basic usage
#' model <- lm(Sepal.Width ~ Species, data = iris)
#' get_emcontrasts(model)
#' @examplesIf insight::check_if_installed("emmeans", quietly = TRUE)
#' # Basic usage
#' model <- lm(Sepal.Width ~ Species, data = iris)
#' get_emcontrasts(model)
#'
#' # Dealing with interactions
#' model <- lm(Sepal.Width ~ Species * Petal.Width, data = iris)
#' # By default: selects first factor
#' get_emcontrasts(model)
#' # Can also run contrasts between points of numeric
#' get_emcontrasts(model, contrast = "Petal.Width", length = 3)
#' # Or both
#' get_emcontrasts(model, contrast = c("Species", "Petal.Width"), length = 2)
#' # Or with custom specifications
#' estimate_contrasts(model, contrast = c("Species", "Petal.Width=c(1, 2)"))
#' # Can fixate the numeric at a specific value
#' get_emcontrasts(model, fixed = "Petal.Width")
#' # Or modulate it
#' get_emcontrasts(model, by = "Petal.Width", length = 4)
#' }
#' # Dealing with interactions
#' model <- lm(Sepal.Width ~ Species * Petal.Width, data = iris)
#' # By default: selects first factor
#' get_emcontrasts(model)
#' # Can also run contrasts between points of numeric
#' get_emcontrasts(model, contrast = "Petal.Width", length = 3)
#' # Or both
#' get_emcontrasts(model, contrast = c("Species", "Petal.Width"), length = 2)
#' # Or with custom specifications
#' estimate_contrasts(model, contrast = c("Species", "Petal.Width=c(1, 2)"))
#' # Or modulate it
#' get_emcontrasts(model, by = "Petal.Width", length = 4)
#' @export
get_emcontrasts <- function(model,
contrast = NULL,
by = NULL,
fixed = NULL,
transform = "none",
method = "pairwise",
...) {
# check if available
insight::check_if_installed("emmeans")

# Guess arguments
my_args <- .guess_emcontrasts_arguments(model, contrast, by, fixed, ...)
my_args <- .guess_emcontrasts_arguments(model, contrast, by, ...)

# Run emmeans
estimated <- emmeans::emmeans(
Expand All @@ -57,7 +52,6 @@ get_emcontrasts <- function(model,
attr(out, "contrast") <- my_args$contrast
attr(out, "at") <- my_args$by
attr(out, "by") <- my_args$by
attr(out, "fixed") <- my_args$fixed
out
}

Expand All @@ -74,7 +68,6 @@ model_emcontrasts <- get_emcontrasts
.guess_emcontrasts_arguments <- function(model,
contrast = NULL,
by = NULL,
fixed = NULL,
...) {
# Gather info
predictors <- insight::find_predictors(model, effects = "fixed", flatten = TRUE, ...)
Expand All @@ -91,6 +84,6 @@ model_emcontrasts <- get_emcontrasts
contrast <- predictors
}

my_args <- list(contrast = contrast, by = by, fixed = fixed)
my_args <- list(contrast = contrast, by = by)
.format_emmeans_arguments(model, args = my_args, data = model_data, ...)
}
47 changes: 14 additions & 33 deletions R/get_emmeans.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@
#' functions.
#'
#' @param model A statistical model.
#' @param fixed A character vector indicating the names of the predictors to be
#' "fixed" (i.e., maintained), so that the estimation is made at these values.
#' @param transform Is passed to the `type` argument in
#' `emmeans::emmeans()`. See
#' [this vignette](https://CRAN.R-project.org/package=emmeans/vignettes/transformations.html).
#' Can be `"none"` (default for contrasts), `"response"`
#' (default for means), `"mu"`, `"unlink"`, `"log"`.
#' `"none"` will leave the values on scale of the linear predictors.
#' `"response"` will transform them on scale of the response variable.
#' Thus for a logistic model, `"none"` will give estimations expressed in
#' log-odds (probabilities on logit scale) and `"response"` in terms of
#' probabilities.
#' @param transform Is passed to the `type` argument in `emmeans::emmeans()`.
#' See [this vignette](https://CRAN.R-project.org/package=emmeans/vignettes/transformations.html).
#' Can be `"none"` (default for contrasts), `"response"` (default for means),
#' `"mu"`, `"unlink"`, `"log"`. `"none"` will leave the values on scale of the
#' linear predictors. `"response"` will transform them on scale of the response
#' variable. Thus for a logistic model, `"none"` will give estimations expressed
#' in log-odds (probabilities on logit scale) and `"response"` in terms of
#' probabilities.
#' @param by The predictor variable(s) at which to evaluate the desired effect
#' / mean / contrasts. Other predictors of the model that are not included
#' here will be collapsed and "averaged" over (the effect will be estimated
#' across them).
#' / mean / contrasts. Other predictors of the model that are not included
#' here will be collapsed and "averaged" over (the effect will be estimated
#' across them).
#' @param ... Other arguments passed for instance to [insight::get_datagrid()].
#'
#' @examples
Expand All @@ -49,14 +45,13 @@
#' @export
get_emmeans <- function(model,
by = "auto",
fixed = NULL,
transform = "response",
...) {
# check if available
insight::check_if_installed("emmeans")

# Guess arguments
my_args <- .guess_emmeans_arguments(model, by, fixed, ...)
my_args <- .guess_emmeans_arguments(model, by, ...)


# Run emmeans
Expand All @@ -78,7 +73,6 @@ get_emmeans <- function(model,

attr(estimated, "at") <- my_args$by
attr(estimated, "by") <- my_args$by
attr(estimated, "fixed") <- my_args$fixed
estimated
}

Expand All @@ -91,7 +85,7 @@ model_emmeans <- get_emmeans
# =========================================================================
# HELPERS ----------------------------------------------------------------
# =========================================================================
# This function is the actual equivalent of .get_marginalmeans(); both being used
# This function is the actual equivalent of get_marginalmeans(); both being used
# in estimate_means

#' @keywords internal
Expand Down Expand Up @@ -122,7 +116,6 @@ model_emmeans <- get_emmeans

attr(means, "at") <- info$by
attr(means, "by") <- info$by
attr(means, "fixed") <- info$fixed
means
}

Expand All @@ -135,7 +128,6 @@ model_emmeans <- get_emmeans
#' @keywords internal
.guess_emmeans_arguments <- function(model,
by = NULL,
fixed = NULL,
...) {
# Gather info
predictors <- insight::find_predictors(model, effects = "fixed", flatten = TRUE, ...)
Expand All @@ -150,7 +142,7 @@ model_emmeans <- get_emmeans
insight::format_alert(paste0("We selected `by = c(", toString(paste0('"', by, '"')), ")`."))
}

my_args <- list(by = by, fixed = fixed)
my_args <- list(by = by)
.format_emmeans_arguments(model, args = my_args, data = my_data, ...)
}

Expand All @@ -177,7 +169,6 @@ model_emmeans <- get_emmeans
} else {
if (!is.null(args$by) && all(args$by == "all")) {
target <- insight::find_predictors(model, effects = "fixed", flatten = TRUE)
target <- target[!target %in% args$fixed]
} else {
target <- args$by
}
Expand All @@ -200,16 +191,6 @@ model_emmeans <- get_emmeans
}
}

# Deal with 'fixed'
if (!is.null(args$fixed)) {
fixed <- insight::get_datagrid(data[args$fixed], by = NULL, ...)
if (is.null(args$data_matrix)) {
args$data_matrix <- fixed
} else {
args$data_matrix <- merge(args$data_matrix, fixed)
}
}

# Get 'specs' and 'at'
# --------------------
if (is.null(args$data_matrix)) {
Expand Down
7 changes: 2 additions & 5 deletions R/get_emtrends.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@
get_emtrends <- function(model,
trend = NULL,
by = NULL,
fixed = NULL,
...) {
# check if available
insight::check_if_installed("emmeans")

# Guess arguments
my_args <- .guess_emtrends_arguments(model, trend, by, fixed, ...)
my_args <- .guess_emtrends_arguments(model, trend, by, ...)

# Run emtrends
estimated <- emmeans::emtrends(
Expand All @@ -40,7 +39,6 @@ get_emtrends <- function(model,
attr(estimated, "trend") <- my_args$trend
attr(estimated, "at") <- my_args$by
attr(estimated, "by") <- my_args$by
attr(estimated, "fixed") <- my_args$fixed
estimated
}

Expand All @@ -56,7 +54,6 @@ model_emtrends <- get_emtrends
.guess_emtrends_arguments <- function(model,
trend = NULL,
by = NULL,
fixed = NULL,
...) {
# Gather info
predictors <- insight::find_predictors(model, effects = "fixed", flatten = TRUE, ...)
Expand All @@ -75,6 +72,6 @@ model_emtrends <- get_emtrends
trend <- trend[1]
}

my_args <- list(trend = trend, by = by, fixed = fixed)
my_args <- list(trend = trend, by = by)
.format_emmeans_arguments(model, args = my_args, data = model_data, ...)
}
Loading
Loading