Partial Eta-Squared (ηp²)
The engine for Unique-Variance Discovery. Partial η² audits the proportion of variance 'stolen' from the error pool by a specific factor, reveal the pure influence of an intervention while ignoring secondary noise.
What is it?
Partial Eta-Squared (ηp²) is designed to mathematically isolate and quantify the magnitude of an observed outcome or model factor, independently of sample size.
The engine for Unique-Variance Discovery. Partial η² audits the proportion of variance 'stolen' from the error pool by a specific factor, reveal the pure influence of an intervention while ignoring secondary noise.
Goals & Indications
- Unique Signal Audit: Isolate the specific predictive power of one factor while mathematically 'blocking out' other variables.
- Error-Pool Discovery: Determine what percentage of the 'Unexplained' variance is captured by your primary treatment effect.
- Interaction Precision Strike: Quantify the magnitude of synergistic interactions in complex, multi-factor ANOVA grids.
Core Idea Diagram
Claims tested
How it works
- Obtain Factor Sum of Squares (SS_factor) and Residual Sum of Squares (SS_error).
- Remove other model factor variances from the denominator calculation.
- Calculate partial explained variance: partial eta² = SS_factor / (SS_factor + SS_error).
- Evaluate factor impact controlling for other covariates.
Assumptions
Important Note
ηp² is SPSS and most statistical software default for ANOVA. It quantifies proportion of variance attributable to a factor AFTER partialling out other factors. Unlike η², ηp² is comparable across studies with different numbers of factors. Always report with factorial ANOVA results.
Worked Example
| Factor SS | Error SS | Other SS | η² vs ηₚ² |
|---|---|---|---|
| 20.0 | 50.0 | 30.0 | 20.0% vs 28.6% |
Denominator Exclusion Laboratory
Slide the other factor sum of squares. Watch how Partial Eta-squared ignores other factors, representing a larger “partial” effect than standard Eta-squared.
Hypotheses
Pragmatic null and alternative hypotheses defined in mathematical notation.
H₀: Partial effect size = 0 (the factor explains no variance after removing other effects)
Hₐ: Partial effect size > 0 (the factor explains unique variance controlling for other factors)
ηp² is SPSS and most statistical software default for ANOVA. It quantifies proportion of variance attributable to a factor AFTER partialling out other factors. Unlike η², ηp² is comparable across studies with different numbers of factors. Always report with factorial ANOVA results.
Assumptions
The core mathematical criteria needed to ensure that statistical testing remains unbiased and valid.
Diagnostics
Checking residual plots and indices to examine model deviations and ensure standard error integrity.
- ANOVA assumption checks (Levene's, Mauchly's sphericity, Q-Q plots)
- Calculate ηp² for each main effect and interaction separately
- Compare ηp² across factors to identify largest effects
- Verify ηp² ≥ η² for all effects (mathematical requirement)
- Bootstrap 95% CI for ηp² (addresses sampling variability)
- Compare η² vs ηp² side-by-side to show difference
- Convert to Cohen's f for power analysis: f = √(ηp²/(1-ηp²))
- Apply Cohen's benchmarks: .01 small, .06 medium, .14 large
- Check for interaction effects before interpreting main effects
- Sensitivity analysis: effect size with/without outliers
- Visualization: interaction plots with effect size annotations
Applied Minds
Review concrete study examples, data layout guidelines, and copy executable syntax scripts.
2×3 Factorial ANOVA - Diet (2 levels) × Exercise (3 levels) on Weight Loss
Research question: Do diet type and exercise frequency interact to affect weight loss? Design: 2×3 factorial between-subjects (Diet: Low-carb vs Low-fat × Exercise: None, Moderate, Intense). N=120 (n=20 per cell). Outcome: Weight loss in kg over 12 weeks. Compute ηp² for main effects and interaction. Compare to η² to show why ηp² preferred in factorial designs.
# Partial eta-squared in 2×3 factorial ANOVA
library(effectsize)
library(tidyverse)
library(ggplot2)
set.seed(2025)
# Generate factorial design data
# True effects: Diet main effect (low-carb better), Exercise main effect (more = better),
# Interaction: low-carb benefits more from intense exercise
data <- expand.grid(
diet = c("LowCarb", "LowFat"),
exercise = c("None", "Moderate", "Intense"),
rep = 1:20
) %>%
mutate(
# Population means for each cell
weight_loss = case_when(
diet == "LowCarb" & exercise == "None" ~ rnorm(20, 3.5, 1.8),
diet == "LowCarb" & exercise == "Moderate" ~ rnorm(20, 6.2, 2.0),
diet == "LowCarb" & exercise == "Intense" ~ rnorm(20, 9.8, 2.2), # Interaction: big boost
diet == "LowFat" & exercise == "None" ~ rnorm(20, 2.8, 1.7),
diet == "LowFat" & exercise == "Moderate" ~ rnorm(20, 5.0, 1.9),
diet == "LowFat" & exercise == "Intense" ~ rnorm(20, 6.5, 2.0) # Smaller boost
)
)
# Descriptive statistics
cat("=== Cell Means(n=20 per cell) ===", "\n")
data %>%
group_by(diet, exercise) %>%
summarise(M = mean(weight_loss), SD = sd(weight_loss), .groups='drop') %>%
print()
# Two-way ANOVA
model <- aov(weight_loss ~ diet * exercise, data=data)
anova_table <- summary(model)[[1]]
print(anova_table)
# Manual calculation of η² and ηp²
cat("\n=== Manual Calculation of Effect Sizes ===", "\n")
# Extract SS values
SS_diet <- anova_table["diet", "Sum Sq"]
SS_exercise <- anova_table["exercise", "Sum Sq"]
SS_interaction <- anova_table["diet:exercise", "Sum Sq"]
SS_error <- anova_table["Residuals", "Sum Sq"]
SS_total <- SS_diet + SS_exercise + SS_interaction + SS_error
df_diet <- anova_table["diet", "Df"]
df_exercise <- anova_table["exercise", "Df"]
df_interaction <- anova_table["diet:exercise", "Df"]
MS_error <- anova_table["Residuals", "Mean Sq"]
# η² (proportion of TOTAL variance)
eta_sq_diet <- SS_diet / SS_total
eta_sq_exercise <- SS_exercise / SS_total
eta_sq_interaction <- SS_interaction / SS_total
eta_sq_sum <- eta_sq_diet + eta_sq_exercise + eta_sq_interaction
cat("\n--- Regular η² (proportion of TOTAL variance) ---\n")
cat(sprintf("η²_Diet = %.3f (%.1f%%)\n", eta_sq_diet, eta_sq_diet*100))
cat(sprintf("η²_Exercise = %.3f (%.1f%%)\n", eta_sq_exercise, eta_sq_exercise*100))
cat(sprintf("η²_Interaction = %.3f (%.1f%%)\n", eta_sq_interaction, eta_sq_interaction*100))
cat(sprintf("Sum of η² = %.3f (sums to < 1.0, excludes error)\n", eta_sq_sum))
# ηp² (proportion of ERROR variance after removing other effects)
partial_eta_sq_diet <- SS_diet / (SS_diet + SS_error)
partial_eta_sq_exercise <- SS_exercise / (SS_exercise + SS_error)
partial_eta_sq_interaction <- SS_interaction / (SS_interaction + SS_error)
partial_eta_sq_sum <- partial_eta_sq_diet + partial_eta_sq_exercise + partial_eta_sq_interaction
cat("\n--- Partial ηp² (proportion of variance after removing OTHER factors) ---\n")
cat(sprintf("ηp²_Diet = %.3f (%.1f%% of Diet+Error variance)\n",
partial_eta_sq_diet, partial_eta_sq_diet*100))
cat(sprintf("ηp²_Exercise = %.3f (%.1f%% of Exercise+Error variance)\n",
partial_eta_sq_exercise, partial_eta_sq_exercise*100))
cat(sprintf("ηp²_Interaction = %.3f (%.1f%% of Interaction+Error variance)\n",
partial_eta_sq_interaction, partial_eta_sq_interaction*100))
cat(sprintf("Sum of ηp² = %.3f (CAN EXCEED 1.0! Not additive!)\n", partial_eta_sq_sum))
cat("\n--- KEY DIFFERENCE ---\n")
cat("ηp² > η² because denominator excludes variance from OTHER factors\n")
cat(sprintf("Diet: ηp²=%.3f vs η²=%.3f (ratio: %.2f)\n",
partial_eta_sq_diet, eta_sq_diet, partial_eta_sq_diet/eta_sq_diet))
cat(sprintf("Exercise: ηp²=%.3f vs η²=%.3f (ratio: %.2f)\n",
partial_eta_sq_exercise, eta_sq_exercise, partial_eta_sq_exercise/eta_sq_exercise))
# Using effectsize package (recommended)
cat("\n=== effectsize Package(Recommended) ===", "\n")
cat("\n--- η² ---\n")
print(eta_squared(model, partial=FALSE))
cat("\n--- ηp² ---\n")
print(eta_squared(model, partial=TRUE))
cat("\n--- ω² (less biased) ---\n")
print(omega_squared(model))
# Interpretation with Cohen's benchmarks
cat("\n=== Interpretation(Cohen 1988 benchmarks) ===", "\n")
cat("Small: .01, Medium: .06, Large: .14\n\n")
interpret_effect <- function(value, name) {
magnitude <- ifelse(value >= .14, "LARGE",
ifelse(value >= .06, "Medium", "Small"))
cat(sprintf("%s: ηp²=%.3f → %s effect\n", name, value, magnitude))
}
interpret_effect(partial_eta_sq_diet, "Diet")
interpret_effect(partial_eta_sq_exercise, "Exercise")
interpret_effect(partial_eta_sq_interaction, "Diet×Exercise")
# Convert to Cohen's f for power analysis
cat("\n=== Conversion to Cohen's f(for G*Power) ===", "\n")
f_diet <- sqrt(partial_eta_sq_diet / (1 - partial_eta_sq_diet))
f_exercise <- sqrt(partial_eta_sq_exercise / (1 - partial_eta_sq_exercise))
f_interaction <- sqrt(partial_eta_sq_interaction / (1 - partial_eta_sq_interaction))
cat(sprintf("Diet: f = %.3f\n", f_diet))
cat(sprintf("Exercise: f = %.3f\n", f_exercise))
cat(sprintf("Interaction: f = %.3f\n", f_interaction))
cat("Cohen's f benchmarks: .10 small, .25 medium, .40 large\n")
# Bootstrap CI for ηp² (Diet effect)
cat("\n=== Bootstrap 95% CI for ηp² (Diet) ===", "\n")
library(boot)
boot_partial_eta_diet <- function(data, indices) {
d <- data[indices, ]
model <- aov(weight_loss ~ diet * exercise, data=d)
SS <- summary(model)[[1]][, "Sum Sq"]
SS_diet <- SS[1]
SS_error <- SS[4]
SS_diet / (SS_diet + SS_error)
}
boot_results <- boot(data, boot_partial_eta_diet, R=1000)
boot_ci <- boot.ci(boot_results, type="perc")
cat(sprintf("ηp²_Diet = %.3f, 95%% CI [%.3f, %.3f]\n",
partial_eta_sq_diet, boot_ci$percent[4], boot_ci$percent[5]))
# Visualization: Interaction plot with effect sizes
cat("\n=== Creating Interaction Plot ===", "\n")
means_plot <- data %>%
group_by(diet, exercise) %>%
summarise(M = mean(weight_loss),
SE = sd(weight_loss)/sqrt(n()),
.groups='drop') %>%
mutate(exercise = factor(exercise, levels=c("None", "Moderate", "Intense")))
p1 <- ggplot(means_plot, aes(x=exercise, y=M, color=diet, group=diet)) +
geom_line(linewidth=1.3) +
geom_point(size=4) +
geom_errorbar(aes(ymin=M-SE, ymax=M+SE), width=0.15, linewidth=1) +
labs(title="Diet × Exercise Interaction on Weight Loss",
subtitle=sprintf("ηp²(Interaction)=%.3f (LARGE effect)", partial_eta_sq_interaction),
x="Exercise Frequency", y="Weight Loss(kg)",
color="Diet Type") +
theme_classic(base_size=14) +
theme(legend.position="top")
print(p1)
# Effect size comparison plot
effect_data <- data.frame(
Factor = rep(c("Diet", "Exercise", "Interaction"), 2),
Type = rep(c("η²", "ηp²"), each=3),
Value = c(eta_sq_diet, eta_sq_exercise, eta_sq_interaction,
partial_eta_sq_diet, partial_eta_sq_exercise, partial_eta_sq_interaction)
)
p2 <- ggplot(effect_data, aes(x=Factor, y=Value, fill=Type)) +
geom_bar(stat="identity", position="dodge", width=0.7) +
geom_hline(yintercept=0.01, linetype="dashed", color="gray50", alpha=0.7) +
geom_hline(yintercept=0.06, linetype="dashed", color="orange", alpha=0.7) +
geom_hline(yintercept=0.14, linestyle="dashed", color="red", alpha=0.7) +
annotate("text", x=3.3, y=0.01, label="Small", hjust=0, size=3) +
annotate("text", x=3.3, y=0.06, label="Medium", hjust=0, size=3) +
annotate("text", x=3.3, y=0.14, label="Large", hjust=0, size=3) +
labs(title="η² vs ηp²: Why ηp² is Larger",
subtitle="ηp² removes other factor variance from denominator",
y="Effect Size", fill="Metric") +
theme_classic(base_size=14) +
coord_cartesian(xlim=c(0.5, 3.8))
print(p2)
# APA-style results
cat("\n=== APA-Style Results ===", "\n")
cat(sprintf(
"A 2×3 factorial ANOVA revealed significant main effects of diet, F(%d, %d) = %.2f, p < .001, ηp² = %.2f (large), and exercise, F(%d, %d) = %.2f, p < .001, ηp² = %.2f (large), as well as a significant Diet×Exercise interaction, F(%d, %d) = %.2f, p < .001, ηp² = %.2f (large). The interaction indicated that low-carb diets benefited more from intense exercise(M=%.1f kg) compared to low-fat diets(M=%.1f kg), while differences were smaller at moderate exercise levels. Partial eta-squared values indicate that diet, exercise, and their interaction each explained substantial unique variance in weight loss after controlling for other factors in the model.\n",
df_diet, anova_table["Residuals", "Df"],
anova_table["diet", "F value"], partial_eta_sq_diet,
df_exercise, anova_table["Residuals", "Df"],
anova_table["exercise", "F value"], partial_eta_sq_exercise,
df_interaction, anova_table["Residuals", "Df"],
anova_table["diet:exercise", "F value"], partial_eta_sq_interaction,
means_plot %>% filter(diet=="LowCarb", exercise=="Intense") %>% pull(M),
means_plot %>% filter(diet=="LowFat", exercise=="Intense") %>% pull(M)
))Diet: F(1,114)=28.5, p<.001, ηp²=.20 (large); Exercise: F(2,114)=52.3, p<.001, ηp²=.48 (large); Interaction: F(2,114)=12.7, p<.001, ηp²=.18 (large). All three effects show large effect sizes. The interaction reveals that low-carb diets benefit disproportionately from intense exercise (M=9.8 kg) compared to low-fat diets (M=6.5 kg), suggesting diet type moderates exercise effectiveness. ηp² values exceed η² values because partial eta-squared removes other factor variance from the denominator, providing a standardized metric comparable across studies with different factorial designs.
Alternatives
Structured fallback pathways for choosing alternative tests when normality or slopes requirements fail.
- Partial Omega-Squared (ωp²) — The mandatory pivot for small factorial samples to ensure unbiased discovery.
- Generalized Eta-Squared (ηG²) — Use this index to compare effects across different experimental structures (e.g., between-subjects vs. mixed).
- Type III SS Strike — Use the sequential sum of squares to protect the partial variance calculation.
Post-hoc
Group mean comparisons and correction controls (e.g. Tukey HSD, Bonferroni) to protect against Family-Wise Error Rates.
- Compare with partial omega-squared (less biased)
- Compare with generalized eta-squared for repeated measures
- Bootstrap confidence intervals
- Note: partial eta-squared values are typically larger than eta-squared
- Convert to Cohen's f for power analysis: f = sqrt(partial_eta² / (1 - partial_eta²))
Partial eta-squared measures effect size controlling for other factors. Post-hoc tests are not applicable.
Effect Size
Understanding effect sizes (e.g., Cohen's d, Partial Eta-Squared) and clinical impact benchmarks.
Proportion of variance explained by factor AFTER removing other effects. Small: .01, Medium: .06, Large: .14 (Cohen, 1988). Standard for factorial/RM ANOVA.
Proportion of TOTAL variance explained. Use in one-way ANOVA. ηp² ≥ η² always in multifactor designs.
Less biased partial effect size. Adjusts ηp² for sampling error. RECOMMENDED for population inference in factorial designs.
Comparable across studies with different designs. Adjusts for manipulated vs measured factors.
Conversion: f = √(ηp² / (1 - ηp²)). Used for power analysis in G*Power. f = .10 small, .25 medium, .40 large.
0.2
0.5
0.8
Sample Size
Guidelines for minimum sample requirements and power analysis parameters.
The 'Unique Signal' Minimum: A minimum of 20 participants per individual cell is essential. Partial η² depends on the 'Residual' pool—if noise is high, the unique signal becomes invisible.
| Effect Size | Parameters | Required n |
|---|---|---|
| Small Effect | ηp² = .01 (Small) | n ≈ 800 total |
| Medium Effect | ηp² = .06 (Medium) | n ≈ 130 total |
| Large Effect | ηp² = .14 (Large) | n ≈ 50 total |
The 'Inflation Paradox': ηp² is often much larger than η² because it ignores the variance owned by other predictors. Reporting both is elite—it proves your predictor is strong both 'Globally' and 'Uniquely'.
Reporting
How to compile statistical results into publication prose matching APA and journal style guides.
A factorial/repeated measures/mixed ANOVA revealed a significant/non-significant main effect of Factor/interaction, F(df_effect, df_error) = X.XX, p = .XXX, ηp² = .XX, 95% CI .XX, .XX, indicating a small/medium/large effect. The factor explained approximately X% of the variance in DV after controlling for other factors.
- F-statistic with degrees of freedom
- p-value
- Partial eta-squared (ηp²) for each effect
- 95% confidence interval (bootstrap preferred)
- Effect size interpretation (small/medium/large with Cohen's benchmarks)
- Descriptive statistics per cell (M, SD, n)
- Interaction effects should be reported before main effects when significant
Manuscript Lab
Copy standard summary tables and forensic reporting grids to outline analysis details.
| Factor | Partial η² | Interpretation | 95% CI |
|---|---|---|---|
| Treatment | .18 | Large Effect | [.08, .28] |
| Severity | .24 | Large Effect | [.14, .34] |
| Treatment × Severity | .08 | Medium Effect | [.01, .15] |
The 'Slice of the Pie'. Represents the proportion of variance in the outcome that is uniquely owned by the factor, AFTER removing variance from other factors.
The Stability Range. If the CI does not cross zero, the effect is robust across the population.
Command Center
Syntax libraries and function parameters for executing calculations in stats packages.
# 1. Extract ηp² from ANOVA object
effectsize::eta_squared(anova_model, partial = TRUE)
# 2. Extract Generalized Eta-Squared (GES)
# Preferred for Repeated Measures designs
effectsize::eta_squared(anova_model, generalized = TRUE)Partial Eta-Squared is often 'Inflated'—it adds up to more than 100% across factors. Always consider reporting 'Generalized Eta-Squared' (GES) for more realistic variance partitioning.
# Model Performance Dashboard
performance::model_performance(anova_model)Common Mistakes
Analytical caveats and corrections to maintain modeling integrity.
References
Scholarly lineage and citation keys grounding the statistical framework.