| Title: | Partial Eta-Squared for Crossed, Nested, and Mixed Linear Mixed Models |
| Version: | 0.2.0 |
| Description: | Computes partial eta-squared effect sizes for fixed effects in linear mixed models fitted with the 'lme4' package. Supports crossed, nested, and mixed (crossed-and-nested) random effects structures with any number of grouping factors. Mixed designs handle cases where grouping factors are simultaneously crossed with some variables and nested within others (e.g., photos nested within models, but both crossed with participants). Random slope variances are translated to the outcome scale using a variance decomposition approach, correctly accounting for predictor scaling and interaction terms. Both general and operative effect sizes are provided. Methods are based on Correll, Mellinger, McClelland, and Judd (2020) <doi:10.1016/j.tics.2019.12.009>, Correll, Mellinger, and Pedersen (2022) <doi:10.3758/s13428-021-01687-2>, and Rights and Sterba (2019) <doi:10.1037/met0000184>. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/bcohen0901/pecanr |
| BugReports: | https://github.com/bcohen0901/pecanr/issues |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| Imports: | lme4 |
| Suggests: | spelling, testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| Language: | en-US |
| NeedsCompilation: | no |
| Packaged: | 2026-03-27 01:24:50 UTC; brandoncohen |
| Author: | Brandon Cohen |
| Maintainer: | Brandon Cohen <brandon.cohen-1@colorado.edu> |
| Repository: | CRAN |
| Date/Publication: | 2026-04-12 02:20:02 UTC |
pecanr: Partial Eta-Squared for Crossed, Nested, and Mixed Linear Mixed Models
Description
Computes partial eta-squared effect sizes for fixed effects in linear mixed models fitted with the 'lme4' package. Supports crossed, nested, and mixed (crossed-and-nested) random effects structures with any number of grouping factors. Mixed designs handle cases where grouping factors are simultaneously crossed with some variables and nested within others (e.g., photos nested within models, but both crossed with participants). Random slope variances are translated to the outcome scale using a variance decomposition approach, correctly accounting for predictor scaling and interaction terms. Both general and operative effect sizes are provided. Methods are based on Correll, Mellinger, McClelland, and Judd (2020) doi:10.1016/j.tics.2019.12.009, Correll, Mellinger, and Pedersen (2022) doi:10.3758/s13428-021-01687-2, and Rights and Sterba (2019) doi:10.1037/met0000184.
Author(s)
Maintainer: Brandon Cohen brandon.cohen-1@colorado.edu (ORCID)
Authors:
Joshua Correll joshua.correll@colorado.edu (ORCID) [thesis advisor]
See Also
Useful links:
Batch Calculate Partial Eta-Squared for Multiple Effects
Description
Calculates partial eta-squared for all fixed effects (excluding the intercept) in a model.
Usage
batch_eta2p(
model,
data,
design = c("crossed", "nested", "mixed"),
subj_var = NULL,
item_var = NULL,
cross_vars = NULL,
nest_vars = NULL,
operative = FALSE,
verbose = FALSE
)
Arguments
model |
A fitted model object from |
data |
Data frame used to fit the model. |
design |
Character string: |
subj_var |
Character string specifying the subject/participant grouping
variable. Retained for backward compatibility; prefer |
item_var |
Character string specifying the item/stimulus grouping
variable. Retained for backward compatibility; prefer |
cross_vars |
Character vector of grouping variable names that are
crossed with each other and with the nested hierarchy
(e.g., |
nest_vars |
Character vector of nesting variables ordered from lowest
to highest level (e.g., |
operative |
Logical. If |
verbose |
Logical. If |
Value
A data frame with one row per effect containing:
effect |
Name of the fixed effect. |
eta2p |
Partial eta-squared value. |
effect_level |
Effect level (nested/mixed designs only). |
variance_effect |
Variance attributed to the effect. |
variance_error |
Error variance used in the denominator. |
type |
|
within_subj, within_item |
(Crossed/mixed, operative only) Whether the effect is within subjects / within items. |
Rows are sorted by eta2p in decreasing order.
Partial Eta-Squared for Linear Mixed Models
Description
Calculates partial eta-squared effect sizes for fixed effects in linear mixed models with crossed, nested, or mixed (crossed-and-nested) random effects.
Usage
eta2p(
model,
effect,
data,
design = c("crossed", "nested", "mixed"),
subj_var = NULL,
item_var = NULL,
cross_vars = NULL,
nest_vars = NULL,
effect_level = NULL,
var_x = NULL,
operative = FALSE,
verbose = TRUE
)
Arguments
model |
A fitted model object from |
effect |
Character string specifying the fixed effect to analyze.
Must match a name in |
data |
Data frame used to fit the model. |
design |
Character string: |
subj_var |
Character string specifying the subject/participant grouping
variable. Retained for backward compatibility; prefer |
item_var |
Character string specifying the item/stimulus grouping
variable. Retained for backward compatibility; prefer |
cross_vars |
Character vector of grouping variable names that are
crossed with each other and with the nested hierarchy
(e.g., |
nest_vars |
Character vector of nesting variables ordered from lowest
to highest level (e.g., |
effect_level |
Character string specifying the level at which the effect
varies (e.g., |
var_x |
Optional numeric. Pre-computed variance of the predictor (or
interaction product). If supplied, overrides the internal |
operative |
Logical. If |
verbose |
Logical. If |
Details
Variance decomposition
The function implements a variance decomposition approach for computing partial eta-squared in mixed models. Random slope variances are translated to the outcome scale using:
\sigma^2_{\text{slope}}(Y) = \sigma^2_b \times \sigma^2_X
For interaction effects, \sigma^2_X is computed as the variance of
the actual product term, correctly accounting for centering, scaling, and
predictor correlation. The var_x argument allows bypassing this
computation when the variance is known a priori.
General vs. operative effect sizes
For general effect sizes (default), all variance components appear
in the denominator. For operative effect sizes
(operative = TRUE), only components that contribute to the standard
error of the effect are included. In mixed designs, each grouping factor
(both crossed and nested) is independently classified as
"within" or "between" the focal effect; between-subjects
intercept variances are excluded from the operative denominator.
Mixed designs
Use design = "mixed" when the model contains both crossed and nested
random effects simultaneously. A canonical example is participants viewing
multiple photos of each model (stimulus): photos are nested within models,
but both levels are crossed with participants.
The corresponding lme4 model and eta2p call would be:
fit <- lmer(y ~ x + (1 | participant) + (1 | model) + (1 | photo:model),
data = dat)
eta2p(fit, "x", dat,
design = "mixed",
cross_vars = "participant",
nest_vars = c("photo", "model"))
Residual variance is attributed to the crossed side and counted exactly once; the nested calculator's residual is subtracted to prevent double-counting.
Crossed designs
Supports any number of grouping factors via cross_vars. The
two-argument form (subj_var + item_var) is retained for
backward compatibility and is equivalent to
cross_vars = c(subj_var, item_var).
Value
An object of class "eta2p_lmm" containing:
eta2p |
Partial eta-squared value. |
variance_effect |
Variance explained by the effect. |
variance_error |
Error variance (denominator). |
effect |
Name of the effect. |
design |
Design type: |
operative |
Whether operative effect size was calculated. |
variance_components |
List of individual variance components. For
|
within_between |
(Mixed/crossed designs) Named list or vector
classifying each grouping factor as |
cross_vars |
(Crossed/mixed designs) Crossed grouping variable names. |
nest_vars |
(Nested/mixed designs) Nested grouping variable names. |
n_per_factor |
(Crossed designs) Number of units per crossed factor. |
n_cross |
(Mixed designs) Number of units per crossed factor. |
n_nested |
(Mixed designs) Number of units per nested factor. |
n_levels |
(Nested designs) Number of units per nested level. |
effect_level |
(Nested/mixed designs) Detected or supplied effect level. |
References
Correll, J., Mellinger, C., McClelland, G. H., & Judd, C. M. (2020). Avoid Cohen's 'Small', 'Medium', and 'Large' for Power Analysis. Trends in Cognitive Sciences, 24(3), 200–207. doi:10.1016/j.tics.2019.12.009
Correll, J., Mellinger, C., & Pedersen, E. J. (2022). Flexible approaches for estimating partial eta squared in mixed-effects models with crossed random factors. Behavior Research Methods, 54, 1626–1642. doi:10.3758/s13428-021-01687-2
Rights, J. D., & Sterba, S. K. (2019). Quantifying explained variance in multilevel models: An integrative framework for defining R-squared measures. Psychological Methods, 24(3), 309–338. doi:10.1037/met0000184
Examples
library(lme4)
# --- Two crossed factors (backward-compatible call) ---
set.seed(42)
crossed_data <- data.frame(
y = rnorm(120),
condition = rep(c(-0.5, 0.5), 60),
subject = factor(rep(1:20, each = 6)),
item = factor(rep(1:6, 20))
)
model_c <- lmer(y ~ condition + (1 | subject) + (1 | item),
data = crossed_data)
eta2p(model_c, "condition", crossed_data,
design = "crossed",
subj_var = "subject",
item_var = "item")
# --- Three crossed factors using cross_vars ---
set.seed(42)
three_way_data <- data.frame(
y = rnorm(180),
condition = rep(c(-0.5, 0.5), 90),
subject = factor(rep(1:20, each = 9)),
item = factor(rep(rep(1:6, each = 3), 10)),
rater = factor(rep(1:3, 60))
)
model_3 <- lmer(y ~ condition +
(1 | subject) + (1 | item) + (1 | rater),
data = three_way_data)
eta2p(model_3, "condition", three_way_data,
design = "crossed",
cross_vars = c("subject", "item", "rater"))
# --- Mixed design: photos nested within models, crossed with participants ---
# Participants each view multiple photos of multiple models.
# Photos are nested within models (each photo belongs to one model),
# but both levels are crossed with participants.
set.seed(42)
n_subj <- 30; n_model <- 10; n_photo <- 3
mixed_data <- expand.grid(
participant = factor(seq_len(n_subj)),
photo_id = factor(seq_len(n_model * n_photo))
)
mixed_data$model_id <- factor(
rep(seq_len(n_model), each = n_photo)[as.integer(mixed_data$photo_id)]
)
mixed_data$x <- rnorm(nrow(mixed_data))
mixed_data$y <- rnorm(nrow(mixed_data))
model_m <- lmer(y ~ x +
(1 | participant) +
(1 | model_id) +
(1 | photo_id:model_id),
data = mixed_data)
eta2p(model_m, "x", mixed_data,
design = "mixed",
cross_vars = "participant",
nest_vars = c("photo_id", "model_id"))
# --- Supply predictor variance directly (var_x) ---
eta2p(model_c, "condition", crossed_data,
design = "crossed",
cross_vars = c("subject", "item"),
var_x = 1) # +/-1 binary predictor: var = 1 by design