Skip to content
Merged
13 changes: 10 additions & 3 deletions R/estimate_contrasts.R
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@
#' size will be computed.
#' @param es_type Specifies the type of effect-size measure to estimate when
#' using `effectsize = "boot"`. One of `"unstandardized"`, `"cohens.d"`,
#' `"hedges.g"`, `"cohens.d.sigma"`, `"r"`, or `"akp.robust.d"`. See`
#' effect.type` argument of [bootES::bootES] for details.
#' `"hedges.g"`, `"cohens.d.sigma"`, `"r"`, or `"akp.robust.d"`. See `effect.type`
#' argument of [`bootES::bootES()`] for details. If not specified, defaults to
#' `"cohens.d"`.
#' @param iterations The number of bootstrap resamples to perform.
#' @inheritParams estimate_means
#'
Expand Down Expand Up @@ -301,7 +302,7 @@ estimate_contrasts.default <- function(
keep_iterations = FALSE,
effectsize = NULL,
iterations = 200,
es_type = "cohens.d",
es_type = NULL,
backend = NULL,
verbose = TRUE,
...
Expand All @@ -317,6 +318,12 @@ estimate_contrasts.default <- function(
# validate input
estimate <- .validate_estimate_arg(estimate)
comparison <- .check_for_inequality_comparison(comparison)
# Validate es_type usage
if (is.null(effectsize) && !is.null(es_type)) {
insight::format_error(
"`es_type` can only be used when `effectsize` is specified. Currently `effectsize = NULL`."
)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move these checks into the function that computes the effect sizes, .estimate_contrasts_effectsize().

Copy link
Member

@rempsyc rempsyc Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then we have a minor problem with the default effectsize = NULL (with es_type still specified) because then the checks get skipped and people will not see the error and therefore not understand why es_type is being ignored (or perceived as incorrect values):

if (!is.null(effectsize)) {
out <- .estimate_contrasts_effectsize(
model = model,
estimated = estimated,
contrasts_results = out,
effectsize = effectsize,
bootstraps = iterations,
bootES_type = es_type,
backend = backend
)
}

There's another area of confusion. If people are not allowed to manually specify es_type = "cohens.d" and be faced with the error, they might be confused as to why the defaultis es_type = "cohens.d" nonetheless? So if we change the default to es_type = NULL, then we possibly resolve this ambiguity and also the above problem (so checks can stay within .estimate_contrasts_effectsize()).


if (backend == "emmeans") {
# Emmeans ----------------------------------------------------------------
Expand Down
41 changes: 30 additions & 11 deletions R/estimate_contrasts_effectsize.R
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
.estimate_contrasts_effectsize <- function(model,
estimated,
contrasts_results,
effectsize,
bootstraps,
bootES_type,
backend) {
.estimate_contrasts_effectsize <- function(
model,
estimated,
contrasts_results,
effectsize,
bootstraps,
bootES_type,
backend
) {
# Add standardized effect size
insight::validate_argument(effectsize, c("none", "emmeans", "marginal", "boot"))

if (effectsize == "emmeans" && backend != "emmeans") {
insight::format_error("`effectsize = \"emmeans\"` only possible with `backend = \"emmeans\"`")
insight::format_error(
"`effectsize = \"emmeans\"` only possible with `backend = \"emmeans\"`"
)
}

if (!is.null(bootES_type) && effectsize != "boot") {
insight::format_error("`es_type` can only be used when `effectsize = \"boot\"`.")
}

# Check if the model includes any random effects. Effect size calculations in
Expand All @@ -36,7 +44,8 @@
))
}

switch(effectsize,
switch(
effectsize,
emmeans = {
eff <- emmeans::eff_size(
estimated,
Expand All @@ -54,10 +63,16 @@
# d_adj <- contrasts$t * contrasts$SE / sigma(model) * sqrt(1 - R2)
# New: d_adj <- difference * (1- R2)/ sigma
R2 <- summary(model)$r.squared
d_adj <- contrasts_results$Difference * (1 - R2) / insight::get_sigma(model, verbose = FALSE)
d_adj <- contrasts_results$Difference *
(1 - R2) /
insight::get_sigma(model, verbose = FALSE)
contrasts_results <- cbind(contrasts_results, marginal_d = d_adj)
},
boot = {
# set default
if (is.null(bootES_type)) {
bootES_type <- "cohens.d"
}
insight::check_if_installed("bootES")
dat <- insight::get_data(model)
resp <- insight::find_response(model)
Expand All @@ -84,7 +99,11 @@

eff <- do.call(rbind, es.lists)
eff <- eff[1:3]
names(eff) <- c(bootES_type, paste0(bootES_type, "_CI_low"), paste0(bootES_type, "_CI_high"))
names(eff) <- c(
bootES_type,
paste0(bootES_type, "_CI_low"),
paste0(bootES_type, "_CI_high")
)

contrasts_results <- cbind(contrasts_results, eff)
}
Expand Down
40 changes: 23 additions & 17 deletions R/estimate_means.R
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@
#'
#' The output from `equivalence_test()` returns a column `SGPV`, the "second
#' generation p-value", which is equivalent to the `p (Equivalence)` column when
#' using the `equivalence` argument. It is basically representiv the ROPE coverage
#' using the `equivalence` argument. It is basically representative of the ROPE coverage
#' from the confidence interval of the estimate (i.e. the proportion of the
#' confidence intervals that lies within the region of practical equivalence).
#'
Expand Down Expand Up @@ -414,16 +414,18 @@
#' estimate_means(model, by = "Sepal.Width", length = 3)
#' }
#' @export
estimate_means <- function(model,
by = "auto",
predict = NULL,
ci = 0.95,
estimate = NULL,
transform = NULL,
keep_iterations = FALSE,
backend = NULL,
verbose = TRUE,
...) {
estimate_means <- function(
model,
by = "auto",
predict = NULL,
ci = 0.95,
estimate = NULL,
transform = NULL,
keep_iterations = FALSE,
backend = NULL,
verbose = TRUE,
...
) {
# Process argument ---------------------------------------------------------
# --------------------------------------------------------------------------

Expand Down Expand Up @@ -469,12 +471,16 @@ estimate_means <- function(model,
info <- attributes(estimated)

# Table formatting
attr(means, "table_title") <- c(switch(estimate,
specific = "Model-based Predictions",
typical = "Estimated Marginal Means",
average = "Average Predictions",
population = "Average Counterfactual Predictions"
), "blue")
attr(means, "table_title") <- c(
switch(
estimate,
specific = "Model-based Predictions",
typical = "Estimated Marginal Means",
average = "Average Predictions",
population = "Average Counterfactual Predictions"
),
"blue"
)

attr(means, "table_footer") <- .table_footer(
means,
Expand Down
99 changes: 26 additions & 73 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
@@ -1,45 +1,39 @@
’s
ANCOVAs
Arel
ATE
ATEs
ATT
ATU
Analysing
Arel
Axelsson
BH
BLUPs
Bundock
cdot
Chatton
CJ
coefficients’
diag
Dickerman
Dom
Chatton
DS
Dickerman
EFC
EMM
EMMs
EUROFAMCARE
Fitzsimons
GAMM
GLM's
GLMM
GLMMs
GLM's
GMM
GMMs
Greifer
Heiss
Hernan
Hernán
ICC's
ICCs
IPW
Intersectional
Intersectionality
JOSS
LM
Leckie
Lenth
LM
MAIHDA
Mattan
McCabe
Expand All @@ -49,154 +43,113 @@ Merlo
Mize
Mmmh
Modelisation
Modelling
Møller
Montiel
Mulinari
Møller
Neyman
Olea
Nonresponse
ORCID
Olea
Owww
PCVs
PCV
PCVs
Plagborg
QoL
Psychometrika
QoL
RCTs
README
Rohrer
RStudio
RTs
Ratcliff
Reproducibility
Rescaling
Rohrer
SSM
SV
SVARs
Setosa
Shachar
Spiller
SSM
Subramanian
SV
SVARs
Versicolor
Virginica
Visualisation
Visualising
Wagenmakers
Weisberg
Wemrell
Wiernik
al
analysing
bc
behaviour
blogpost
bocode
bonferroni
bootES
brglm
brms
caregiving
cdot
ception
codecov
computable
coefficients’
conditionspeed
counterfactuals
confounder
confounders
coxme
d'être
d’être
dat
datagrid
datawizard
diag
doi
dpar
d’être
easystats
edu
effectsize
emmeans
emtrends
et
exchangeability
favour
fdr
fmwww
foR
generalizability
geoms
ggplot
github
glmmTMB
glms
grano
grey
hochberg
holm
hommel
http
https
individuals'
interpretable
individuals’
intersectional
intersectionality
intra
io
jmr
joss
labelled
lifecycle
lme
lme4
loess
marginaleffects
marginalizations
mattansb
modelisation
modelled
modelling
natively
nd
nnet
ol
onwards
partialled
patilindrajeets
pscl
pre
quartiles
pscl
rOpenSci
Remotes
raison
recoding
recodings
repec
reproducibility
rescaled
rescales
residualize
residualized
residualizes
rootSolve
rstanarm
salis
spinoff
ssmph
strengejacke
summarised
summarises
terciles
transint
tukey
ultron
uninformativeness
tinyplot
unidimensional
uninformativeness
unstandardizing
usecases
versicolor
virginica
visualisation
visualise
visualising
walkthrough
Nonresponse
tinyplot
’s
Loading
Loading