From c71c68a5ecc45e16bc051fc57d3345e280140fb3 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 19:23:06 +0100 Subject: [PATCH 01/10] Draft marginalcontrasts --- R/estimate_contrasts.R | 89 +++++++++++++++++++++++++-------------- R/get_marginalcontrasts.R | 20 ++++++--- man/estimate_contrasts.Rd | 4 ++ man/get_marginalmeans.Rd | 41 +++++++++++++----- 4 files changed, 107 insertions(+), 47 deletions(-) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index 407f7a42..b0f4ca5d 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -78,17 +78,64 @@ estimate_contrasts <- function(model, ci = 0.95, p_adjust = "holm", method = "pairwise", + backend = "emmeans", ...) { - # Run emmeans - estimated <- get_emcontrasts(model, - contrast = contrast, - by = by, - transform = transform, - method = method, - adjust = p_adjust, - ... + if (backend == "emmeans") { + # Emmeans ------------------------------------------------------------------ + estimated <- get_emcontrasts(model, + contrast = contrast, + by = by, + transform = transform, + method = method, + adjust = p_adjust, + ... + ) + out <- .format_emmeans_contrasts(model, estimated, ci, transform, p_adjust, ...) + } else { + # Marginalmeans ------------------------------------------------------------ + estimated <- get_marginalcontrasts(model, + contrast = contrast, + by = by, + transform = transform, + method = method, + adjust = p_adjust, + ... + ) + out <- .format_marginaleffects_means(estimated, model, transform, ...) + } + + + # Table formatting + attr(out, "table_title") <- c("Marginal Contrasts Analysis", "blue") + attr(out, "table_footer") <- .estimate_means_footer( + out, + info$contrast, + type = "contrasts", + p_adjust = p_adjust ) + # Add attributes + attr(out, "model") <- model + attr(out, "response") <- insight::find_response(model) + attr(out, "ci") <- ci + attr(out, "transform") <- transform + attr(out, "at") <- info$by + attr(out, "by") <- info$by + attr(out, "contrast") <- info$contrast + attr(out, "p_adjust") <- p_adjust + + + # Output + class(out) <- c("estimate_contrasts", "see_estimate_contrasts", class(out)) + out +} + + + +# Table formatting emmeans ---------------------------------------------------- + + +.format_emmeans_contrasts <- function(model, estimated, ci, transform, p_adjust, ...) { info <- attributes(estimated) # Summarize and clean @@ -120,30 +167,10 @@ estimate_contrasts <- function(model, # Merge levels and rest out$contrast <- NULL - out <- cbind(level_cols, out) - - - # Table formatting - attr(out, "table_title") <- c("Marginal Contrasts Analysis", "blue") - attr(out, "table_footer") <- .estimate_means_footer( - out, - info$contrast, - type = "contrasts", - p_adjust = p_adjust - ) + cbind(level_cols, out) +} - # Add attributes - attr(out, "model") <- model - attr(out, "response") <- insight::find_response(model) - attr(out, "ci") <- ci - attr(out, "transform") <- transform - attr(out, "at") <- info$by - attr(out, "by") <- info$by - attr(out, "contrast") <- info$contrast - attr(out, "p_adjust") <- p_adjust +.format_marginaleffects_means <- function() { - # Output - class(out) <- c("estimate_contrasts", "see_estimate_contrasts", class(out)) - out } diff --git a/R/get_marginalcontrasts.R b/R/get_marginalcontrasts.R index c1444750..f8125536 100644 --- a/R/get_marginalcontrasts.R +++ b/R/get_marginalcontrasts.R @@ -1,24 +1,34 @@ #' @rdname get_marginalmeans #' #' @param method Contrast method. +#' @inheritParams get_emcontrasts #' @export get_marginalcontrasts <- function(model, + contrast = NULL, by = NULL, - ci = 0.95, + transform = "none", method = "pairwise", + ci = 0.95, ...) { + # check if available + insight::check_if_installed("marginaleffects") + + # Guess arguments + my_args <- .guess_marginalcontrasts_arguments(model, contrast, by, ...) + out <- estimate_means( model = model, - by = by, + by = my_args$by, ci = ci, hypothesis = method, + transform = transform, backend = "marginaleffects", ... ) - attr(out, "table_title") <- c("Marginal Contrasts Analysis", "blue") - attr(out, "table_footer") <- .estimate_means_footer(out, by = by, type = "contrasts", p_adjust = NULL) - + attr(out, "contrast") <- my_args$contrast + attr(out, "at") <- my_args$by + attr(out, "by") <- my_args$by out } diff --git a/man/estimate_contrasts.Rd b/man/estimate_contrasts.Rd index 105aa50c..7269373e 100644 --- a/man/estimate_contrasts.Rd +++ b/man/estimate_contrasts.Rd @@ -12,6 +12,7 @@ estimate_contrasts( ci = 0.95, p_adjust = "holm", method = "pairwise", + backend = "emmeans", ... ) } @@ -44,6 +45,9 @@ p-value adjustment section in the \code{emmeans::test} documentation.} \item{method}{Contrast method. See same argument in \link[emmeans:contrast]{emmeans::contrast}.} +\item{backend}{Whether to use 'emmeans' or 'marginaleffects' as a backend. +The latter is experimental and some features might not work.} + \item{...}{Other arguments passed for instance to \code{\link[insight:get_datagrid]{insight::get_datagrid()}}.} } \value{ diff --git a/man/get_marginalmeans.Rd b/man/get_marginalmeans.Rd index 3fb16250..fa12ea30 100644 --- a/man/get_marginalmeans.Rd +++ b/man/get_marginalmeans.Rd @@ -9,9 +9,25 @@ \alias{model_marginalmeans} \title{Easy 'avg_predictions' and 'avg_slopes'} \usage{ -get_marginalcontrasts(model, by = NULL, ci = 0.95, method = "pairwise", ...) - -model_marginalcontrasts(model, by = NULL, ci = 0.95, method = "pairwise", ...) +get_marginalcontrasts( + model, + contrast = NULL, + by = NULL, + transform = "none", + method = "pairwise", + ci = 0.95, + ... +) + +model_marginalcontrasts( + model, + contrast = NULL, + by = NULL, + transform = "none", + method = "pairwise", + ci = 0.95, + ... +) get_marginaleffects(model, trend = NULL, by = NULL, ...) @@ -22,27 +38,30 @@ model_marginalmeans(model, by = "auto", transform = NULL, ci = 0.95, ...) \arguments{ \item{model}{A statistical model.} +\item{contrast}{A character vector indicating the name of the variable(s) +for which to compute the contrasts.} + \item{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).} -\item{ci}{Level for confidence intervals.} +\item{transform}{Can be used to easily modulate the \code{type} argument in +\code{marginaleffects::avg_predictions()}. Can be \code{"none"} or \code{"response"}. +\code{"none"} will leave the values on scale of the linear predictors. +\code{"response"} will transform them on scale of the response variable. Thus for +a logistic model, \code{"none"} will give estimations expressed in log-odds +(probabilities on logit scale) and \code{"response"} in terms of probabilities.} \item{method}{Contrast method.} +\item{ci}{Level for confidence intervals.} + \item{...}{Other arguments passed, for instance, to \code{\link[insight:get_datagrid]{insight::get_datagrid()}} or \code{\link[marginaleffects:predictions]{marginaleffects::avg_predictions()}}.} \item{trend}{A character indicating the name of the variable for which to compute the slopes.} - -\item{transform}{Can be used to easily modulate the \code{type} argument in -\code{marginaleffects::avg_predictions()}. Can be \code{"none"} or \code{"response"}. -\code{"none"} will leave the values on scale of the linear predictors. -\code{"response"} will transform them on scale of the response variable. Thus for -a logistic model, \code{"none"} will give estimations expressed in log-odds -(probabilities on logit scale) and \code{"response"} in terms of probabilities.} } \description{ The \code{get_marginalmeans()} function is a wrapper to facilitate the usage of From c51a3a593e9c8fa59f451259cae700eb51f6ef53 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 21:13:30 +0100 Subject: [PATCH 02/10] draft --- R/estimate_contrasts.R | 16 ++++++++++------ R/get_marginalcontrasts.R | 11 +++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index b0f4ca5d..0fbc45f7 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -91,6 +91,7 @@ estimate_contrasts <- function(model, ... ) out <- .format_emmeans_contrasts(model, estimated, ci, transform, p_adjust, ...) + info <- attributes(estimated) } else { # Marginalmeans ------------------------------------------------------------ estimated <- get_marginalcontrasts(model, @@ -98,10 +99,13 @@ estimate_contrasts <- function(model, by = by, transform = transform, method = method, - adjust = p_adjust, + p_adjust = p_adjust, + ci = ci, ... ) - out <- .format_marginaleffects_means(estimated, model, transform, ...) + out <- .format_marginaleffects_contrasts(model, estimated, ci, transform, p_adjust, ...) + ## TODO: needs to be fixed + info <- list(contrast = contrast, by = by) } @@ -136,8 +140,6 @@ estimate_contrasts <- function(model, .format_emmeans_contrasts <- function(model, estimated, ci, transform, p_adjust, ...) { - info <- attributes(estimated) - # Summarize and clean if (insight::model_info(model)$is_bayesian) { out <- cbind(estimated@grid, bayestestR::describe_posterior(estimated, ci = ci, verbose = FALSE, ...)) @@ -171,6 +173,8 @@ estimate_contrasts <- function(model, } -.format_marginaleffects_means <- function() { - +.format_marginaleffects_contrasts <- function(model, estimated, ci, transform, p_adjust, ...) { + groups <- attributes(estimated)$by + contrast <- attributes(estimated)$contrast + estimated } diff --git a/R/get_marginalcontrasts.R b/R/get_marginalcontrasts.R index f8125536..1336b3d5 100644 --- a/R/get_marginalcontrasts.R +++ b/R/get_marginalcontrasts.R @@ -13,22 +13,17 @@ get_marginalcontrasts <- function(model, # check if available insight::check_if_installed("marginaleffects") - # Guess arguments - my_args <- .guess_marginalcontrasts_arguments(model, contrast, by, ...) - out <- estimate_means( model = model, - by = my_args$by, + by = c(contrast, by), ci = ci, hypothesis = method, - transform = transform, + transform = "response", backend = "marginaleffects", ... ) - attr(out, "contrast") <- my_args$contrast - attr(out, "at") <- my_args$by - attr(out, "by") <- my_args$by + attr(out, "contrast") <- contrast out } From 1d041754dbd13956a12860665ca6eb37bd72d47f Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 21:18:41 +0100 Subject: [PATCH 03/10] fix --- R/get_marginalmeans.R | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/R/get_marginalmeans.R b/R/get_marginalmeans.R index fc62be3f..95cc4c78 100644 --- a/R/get_marginalmeans.R +++ b/R/get_marginalmeans.R @@ -120,6 +120,13 @@ model_marginalmeans <- get_marginalmeans info <- insight::model_info(model, verbose = FALSE) non_focal <- setdiff(colnames(model_data), attr(means, "focal_terms")) + # do we have contrasts? For contrasts, we want to keep p-values + if (is.null(list(...)$hypothesis)) { + p_column <- "p" + } else { + p_column <- NULL + } + # estimate name if (!identical(transform, "none") && (info$is_binomial || info$is_bernoulli)) { estimate_name <- "Probability" @@ -129,9 +136,9 @@ model_marginalmeans <- get_marginalmeans # Format params <- suppressWarnings(parameters::model_parameters(means, verbose = FALSE)) - params <- datawizard::data_relocate(params, c("Predicted", "SE", "CI_low", "CI_high"), after = -1, verbose = FALSE) # nolint + params <- datawizard::data_relocate(params, c("Predicted", "SE", "CI_low", "CI_high", "p"), after = -1, verbose = FALSE) # nolint params <- datawizard::data_rename(params, "Predicted", estimate_name) - params <- datawizard::data_remove(params, c("p", "Statistic", "s.value", "S", "CI", "df", "rowid_dedup", non_focal), verbose = FALSE) # nolint + params <- datawizard::data_remove(params, c(p_column, "Statistic", "s.value", "S", "CI", "df", "rowid_dedup", non_focal), verbose = FALSE) # nolint params <- datawizard::data_restoretype(params, model_data) # Store info From e6aeb1be07a1bf6ccd92be083b41499b97ba3487 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 21:27:27 +0100 Subject: [PATCH 04/10] dev --- R/get_marginalmeans.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/R/get_marginalmeans.R b/R/get_marginalmeans.R index 95cc4c78..1547f55f 100644 --- a/R/get_marginalmeans.R +++ b/R/get_marginalmeans.R @@ -123,15 +123,15 @@ model_marginalmeans <- get_marginalmeans # do we have contrasts? For contrasts, we want to keep p-values if (is.null(list(...)$hypothesis)) { p_column <- "p" + # estimate name + if (!identical(transform, "none") && (info$is_binomial || info$is_bernoulli)) { + estimate_name <- "Probability" + } else { + estimate_name <- "Mean" + } } else { p_column <- NULL - } - - # estimate name - if (!identical(transform, "none") && (info$is_binomial || info$is_bernoulli)) { - estimate_name <- "Probability" - } else { - estimate_name <- "Mean" + estimate_name <- "Difference" } # Format From ecbbf57a69f50360dc0f334c97e1e554dbb39e19 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 21:34:37 +0100 Subject: [PATCH 05/10] dev --- R/estimate_contrasts.R | 3 +++ R/get_marginalmeans.R | 18 +++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index 0fbc45f7..9408a634 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -176,5 +176,8 @@ estimate_contrasts <- function(model, .format_marginaleffects_contrasts <- function(model, estimated, ci, transform, p_adjust, ...) { groups <- attributes(estimated)$by contrast <- attributes(estimated)$contrast + + ## TODO: split Parameter column into levels indicated in "contrast", and filter by "by" + estimated } diff --git a/R/get_marginalmeans.R b/R/get_marginalmeans.R index 1547f55f..878c8ca8 100644 --- a/R/get_marginalmeans.R +++ b/R/get_marginalmeans.R @@ -119,26 +119,30 @@ model_marginalmeans <- get_marginalmeans model_data <- insight::get_data(model) info <- insight::model_info(model, verbose = FALSE) non_focal <- setdiff(colnames(model_data), attr(means, "focal_terms")) + is_contrast_analysis <- !is.null(list(...)$hypothesis) # do we have contrasts? For contrasts, we want to keep p-values - if (is.null(list(...)$hypothesis)) { - p_column <- "p" + if (is_contrast_analysis) { + remove_column <- "SE" + estimate_name <- "Difference" + } else { + remove_column <- "p" # estimate name if (!identical(transform, "none") && (info$is_binomial || info$is_bernoulli)) { estimate_name <- "Probability" } else { estimate_name <- "Mean" } - } else { - p_column <- NULL - estimate_name <- "Difference" } # Format params <- suppressWarnings(parameters::model_parameters(means, verbose = FALSE)) - params <- datawizard::data_relocate(params, c("Predicted", "SE", "CI_low", "CI_high", "p"), after = -1, verbose = FALSE) # nolint + params <- datawizard::data_relocate(params, c("Predicted", "SE", "CI_low", "CI_high"), after = -1, verbose = FALSE) # nolint + # move p to the end + params <- datawizard::data_relocate(params, "p", after = -1, verbose = FALSE) params <- datawizard::data_rename(params, "Predicted", estimate_name) - params <- datawizard::data_remove(params, c(p_column, "Statistic", "s.value", "S", "CI", "df", "rowid_dedup", non_focal), verbose = FALSE) # nolint + # remove redundant columns + params <- datawizard::data_remove(params, c(remove_column, "Statistic", "s.value", "S", "CI", "df", "rowid_dedup", non_focal), verbose = FALSE) # nolint params <- datawizard::data_restoretype(params, model_data) # Store info From d59e6a0dfb31f6cd9d91336200aba52b97cb1e83 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 23:27:59 +0100 Subject: [PATCH 06/10] more --- R/get_marginalcontrasts.R | 56 +++++++++++++++++++++++++++++++++++++++ R/get_marginalmeans.R | 1 + man/get_marginalmeans.Rd | 2 ++ 3 files changed, 59 insertions(+) diff --git a/R/get_marginalcontrasts.R b/R/get_marginalcontrasts.R index 1336b3d5..a5169b78 100644 --- a/R/get_marginalcontrasts.R +++ b/R/get_marginalcontrasts.R @@ -9,6 +9,7 @@ get_marginalcontrasts <- function(model, transform = "none", method = "pairwise", ci = 0.95, + p_adjust = "none", ...) { # check if available insight::check_if_installed("marginaleffects") @@ -23,6 +24,8 @@ get_marginalcontrasts <- function(model, ... ) + out <- .p_adjust(model, out, p_adjust, ...) + attr(out, "contrast") <- contrast out } @@ -30,3 +33,56 @@ get_marginalcontrasts <- function(model, #' @rdname get_marginalmeans #' @export model_marginalcontrasts <- get_marginalcontrasts + + +# p-value adjustment ------------------- + +.p_adjust <- function(model, params, p_adjust, ...) { + # extract information + datagrid <- attributes(params)$datagrid + focal <- attributes(params)$focal_terms + statistic <- insight::get_statistic(model)$Statistic + df <- insight::get_df(model) + + # exit on NULL, or if no p-adjustment requested + if (is.null(p_adjust) || identical(p_adjust, "none")) { + return(params) + } + + all_methods <- c(tolower(stats::p.adjust.methods), "tukey", "sidak") + + # needed for rank adjustment + focal_terms <- datagrid[focal] + rank_adjust <- prod(vapply(focal_terms, insight::n_unique, numeric(1))) + + # only proceed if valid argument-value + if (tolower(p_adjust) %in% all_methods) { + if (tolower(p_adjust) %in% tolower(stats::p.adjust.methods)) { + # base R adjustments + params[["p"]] <- stats::p.adjust(params[["p"]], method = p_adjust) + } else if (tolower(p_adjust) == "tukey") { + if (!is.null(statistic)) { + # tukey adjustment + params[["p"]] <- suppressWarnings(stats::ptukey( + sqrt(2) * abs(statistic), + rank_adjust, + df, + lower.tail = FALSE + )) + # for specific contrasts, ptukey might fail, and the tukey-adjustement + # could just be simple p-value calculation + if (all(is.na(params[["p"]]))) { + params[["p"]] <- 2 * stats::pt(abs(statistic), df = df, lower.tail = FALSE) + } + } else if (verbose) { + insight::format_alert("No test-statistic found. P-values were not adjusted.") + } + } else if (tolower(p_adjust) == "sidak") { + # sidak adjustment + params[["p"]] <- 1 - (1 - params[["p"]])^rank_adjust + } + } else if (verbose) { + insight::format_alert(paste0("`p_adjust` must be one of ", toString(all_methods))) + } + params +} diff --git a/R/get_marginalmeans.R b/R/get_marginalmeans.R index 878c8ca8..37f6104f 100644 --- a/R/get_marginalmeans.R +++ b/R/get_marginalmeans.R @@ -102,6 +102,7 @@ get_marginalmeans <- function(model, attr(means, "at") <- my_args$by attr(means, "by") <- my_args$by attr(means, "focal_terms") <- at_specs$varname + attr(means, "datagrid") <- datagrid means } diff --git a/man/get_marginalmeans.Rd b/man/get_marginalmeans.Rd index fa12ea30..bc1d7396 100644 --- a/man/get_marginalmeans.Rd +++ b/man/get_marginalmeans.Rd @@ -16,6 +16,7 @@ get_marginalcontrasts( transform = "none", method = "pairwise", ci = 0.95, + p_adjust = "none", ... ) @@ -26,6 +27,7 @@ model_marginalcontrasts( transform = "none", method = "pairwise", ci = 0.95, + p_adjust = "none", ... ) From f8fda6133569cf9be9fb42c714e2205edd38ddc7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 23:49:26 +0100 Subject: [PATCH 07/10] print --- R/estimate_contrasts.R | 26 ++++++++++++++++++++------ R/get_marginalcontrasts.R | 3 --- man/estimate_contrasts.Rd | 13 ++++++++++--- man/get_marginalmeans.Rd | 2 -- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index 9408a634..aa25a58b 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -7,9 +7,14 @@ #' @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. +#' - For `backend = "emmeans"`, 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. +#' - For `backend = "marginaleffects"`, can be one of `"holm"` (default), +#' `"hochberg"`, `"hommel"`, `"bonferroni"`, `"bh"`, `"by"`, `"fdr"`, +#' `"none"`, `"tukey"` or `"sidak"`. #' #' @inherit estimate_slopes details #' @@ -103,7 +108,7 @@ estimate_contrasts <- function(model, ci = ci, ... ) - out <- .format_marginaleffects_contrasts(model, estimated, ci, transform, p_adjust, ...) + out <- .format_marginaleffects_contrasts(model, estimated, p_adjust, method, ...) ## TODO: needs to be fixed info <- list(contrast = contrast, by = by) } @@ -128,7 +133,6 @@ estimate_contrasts <- function(model, attr(out, "contrast") <- info$contrast attr(out, "p_adjust") <- p_adjust - # Output class(out) <- c("estimate_contrasts", "see_estimate_contrasts", class(out)) out @@ -173,11 +177,21 @@ estimate_contrasts <- function(model, } -.format_marginaleffects_contrasts <- function(model, estimated, ci, transform, p_adjust, ...) { +.format_marginaleffects_contrasts <- function(model, estimated, p_adjust, method, ...) { groups <- attributes(estimated)$by contrast <- attributes(estimated)$contrast + focal_terms <- attributes(estimated)$focal_terms + + estimated <- .p_adjust(model, estimated, p_adjust, ...) + valid_methods <- c( + "pairwise", "reference", "sequential", "meandev","meanotherdev", + "revpairwise", "revreference", "revsequential" + ) ## TODO: split Parameter column into levels indicated in "contrast", and filter by "by" + if (!is.null(method) && is.character(method) && method %in% valid_methods) { + + } estimated } diff --git a/R/get_marginalcontrasts.R b/R/get_marginalcontrasts.R index a5169b78..844fff51 100644 --- a/R/get_marginalcontrasts.R +++ b/R/get_marginalcontrasts.R @@ -9,7 +9,6 @@ get_marginalcontrasts <- function(model, transform = "none", method = "pairwise", ci = 0.95, - p_adjust = "none", ...) { # check if available insight::check_if_installed("marginaleffects") @@ -24,8 +23,6 @@ get_marginalcontrasts <- function(model, ... ) - out <- .p_adjust(model, out, p_adjust, ...) - attr(out, "contrast") <- contrast out } diff --git a/man/estimate_contrasts.Rd b/man/estimate_contrasts.Rd index 7269373e..9361cdc8 100644 --- a/man/estimate_contrasts.Rd +++ b/man/estimate_contrasts.Rd @@ -39,9 +39,16 @@ probabilities.} \item{ci}{Confidence Interval (CI) level. Default to \code{0.95} (\verb{95\%}).} \item{p_adjust}{The p-values adjustment method for frequentist multiple -comparisons. Can be one of \code{"holm"} (default), \code{"tukey"}, \code{"hochberg"}, -\code{"hommel"}, \code{"bonferroni"}, \code{"BH"}, \code{"BY"}, \code{"fdr"} or \code{"none"}. See the -p-value adjustment section in the \code{emmeans::test} documentation.} +comparisons. +\itemize{ +\item For \code{backend = "emmeans"}, can be one of \code{"holm"} (default), \code{"tukey"}, +\code{"hochberg"}, \code{"hommel"}, \code{"bonferroni"}, \code{"BH"}, \code{"BY"}, \code{"fdr"} or +\code{"none"}. See the p-value adjustment section in the \code{emmeans::test} +documentation. +\item For \code{backend = "marginaleffects"}, can be one of \code{"holm"} (default), +\code{"hochberg"}, \code{"hommel"}, \code{"bonferroni"}, \code{"bh"}, \code{"by"}, \code{"fdr"}, +\code{"none"}, \code{"tukey"} or \code{"sidak"}. +}} \item{method}{Contrast method. See same argument in \link[emmeans:contrast]{emmeans::contrast}.} diff --git a/man/get_marginalmeans.Rd b/man/get_marginalmeans.Rd index bc1d7396..fa12ea30 100644 --- a/man/get_marginalmeans.Rd +++ b/man/get_marginalmeans.Rd @@ -16,7 +16,6 @@ get_marginalcontrasts( transform = "none", method = "pairwise", ci = 0.95, - p_adjust = "none", ... ) @@ -27,7 +26,6 @@ model_marginalcontrasts( transform = "none", method = "pairwise", ci = 0.95, - p_adjust = "none", ... ) From e3ef3d16b7fc2f7b6983cb0fcee9f028fb8cf0af Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 23:55:29 +0100 Subject: [PATCH 08/10] fix --- R/get_marginalcontrasts.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/get_marginalcontrasts.R b/R/get_marginalcontrasts.R index 844fff51..bc955b73 100644 --- a/R/get_marginalcontrasts.R +++ b/R/get_marginalcontrasts.R @@ -40,6 +40,7 @@ model_marginalcontrasts <- get_marginalcontrasts focal <- attributes(params)$focal_terms statistic <- insight::get_statistic(model)$Statistic df <- insight::get_df(model) + verbose <- isTRUE(list(...)$verbose) # exit on NULL, or if no p-adjustment requested if (is.null(p_adjust) || identical(p_adjust, "none")) { From 0c54341c55ebe6166308553cc136070547905368 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 23:56:41 +0100 Subject: [PATCH 09/10] docs --- R/estimate_contrasts.R | 11 +++-------- man/estimate_contrasts.Rd | 13 +++---------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index aa25a58b..4d02a69d 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -7,14 +7,9 @@ #' @inheritParams estimate_means #' @inheritParams get_emcontrasts #' @param p_adjust The p-values adjustment method for frequentist multiple -#' comparisons. -#' - For `backend = "emmeans"`, 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. -#' - For `backend = "marginaleffects"`, can be one of `"holm"` (default), -#' `"hochberg"`, `"hommel"`, `"bonferroni"`, `"bh"`, `"by"`, `"fdr"`, -#' `"none"`, `"tukey"` or `"sidak"`. +#' 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 #' diff --git a/man/estimate_contrasts.Rd b/man/estimate_contrasts.Rd index 9361cdc8..7269373e 100644 --- a/man/estimate_contrasts.Rd +++ b/man/estimate_contrasts.Rd @@ -39,16 +39,9 @@ probabilities.} \item{ci}{Confidence Interval (CI) level. Default to \code{0.95} (\verb{95\%}).} \item{p_adjust}{The p-values adjustment method for frequentist multiple -comparisons. -\itemize{ -\item For \code{backend = "emmeans"}, can be one of \code{"holm"} (default), \code{"tukey"}, -\code{"hochberg"}, \code{"hommel"}, \code{"bonferroni"}, \code{"BH"}, \code{"BY"}, \code{"fdr"} or -\code{"none"}. See the p-value adjustment section in the \code{emmeans::test} -documentation. -\item For \code{backend = "marginaleffects"}, can be one of \code{"holm"} (default), -\code{"hochberg"}, \code{"hommel"}, \code{"bonferroni"}, \code{"bh"}, \code{"by"}, \code{"fdr"}, -\code{"none"}, \code{"tukey"} or \code{"sidak"}. -}} +comparisons. Can be one of \code{"holm"} (default), \code{"tukey"}, \code{"hochberg"}, +\code{"hommel"}, \code{"bonferroni"}, \code{"BH"}, \code{"BY"}, \code{"fdr"} or \code{"none"}. See the +p-value adjustment section in the \code{emmeans::test} documentation.} \item{method}{Contrast method. See same argument in \link[emmeans:contrast]{emmeans::contrast}.} From 9e9065f8207937a29f07d15f178d2b50be58b84c Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 16 Dec 2024 23:58:30 +0100 Subject: [PATCH 10/10] structure --- R/estimate_contrasts.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/estimate_contrasts.R b/R/estimate_contrasts.R index 4d02a69d..c46f328b 100644 --- a/R/estimate_contrasts.R +++ b/R/estimate_contrasts.R @@ -172,6 +172,10 @@ estimate_contrasts <- function(model, } + +# Table formatting marginal effects ------------------------------------------- + + .format_marginaleffects_contrasts <- function(model, estimated, p_adjust, method, ...) { groups <- attributes(estimated)$by contrast <- attributes(estimated)$contrast