ANOVA Output Interpreter

ANOVA tests whether three or more groups have meaningfully different averages, and which terms in your model are doing the work. Paste an aov() or car::Anova() table from R to get a per-term plain-English read, eta-squared effect sizes, and a clear verdict on what is driving the variation.

i New to Type I / II / III ANOVA? Read the 4-min primer

What ANOVA does. Analysis of Variance partitions the total variation in an outcome into chunks attributable to each predictor (and to leftover residual noise). Each row in an ANOVA table reports a Sum of Squares (SS), the degrees of freedom (df) it consumed, the resulting Mean Square (SS / df), an F-ratio against the residual mean square, and a p-value.

Why three Types. When predictors are correlated (an unbalanced design), the SS for one term depends on what other terms are already in the model. Type I (sequential) credits each term with the SS it explains after the previously listed terms. Type II adjusts each main effect for all other main effects but ignores interactions. Type III adjusts every term for every other term, including interactions, and matches the marginal-means hypothesis people usually have in mind.

What to report. Beyond F and p, give an effect size: eta-squared (SS_term / SS_total) for the proportion of total variance the term carries, and partial eta-squared (SS_term / (SS_term + SS_resid)) for the share once you set aside the other terms. Conventional cutoffs are 0.01 (small), 0.06 (medium), 0.14 (large), but interpret in your field's context.

Picking which Type. Balanced design with no missingness: all three Types coincide; report any. Unbalanced data and you care about main effects: Type II. Significant interaction or you want SAS-style marginal tests: Type III with sum-to-zero contrasts. Never quote Type I from a model whose term order is not theoretically motivated.

Recomputes every F and p-value from Sum Sq and Df, adds eta-squared, omega-squared and Cohen's f, runs entirely in your browser

Try a real-world example to load.

Awaiting paste…
R code COPY-READY
R Reproduce in R
SS contribution per term VISUAL
Bar height = Sum of Squares per term; residual SS shown in grey.
Paste an ANOVA table to render.
Inference

We recompute each F and p-value from your table's Sum Sq and Df, then read off which group differences are large enough to take seriously.

Read more Anatomy of an ANOVA table
Sum of squares partition: SS_total = sum( (y_i - mean(y))^2 ) SS_term = SS explained by that term SS_resid = leftover residual SS SS_total = sum(SS_term) + SS_resid (Type I, balanced design)
The variance pie. Total variation in y is sliced into chunks, one per term, plus an unexplained residual chunk. The exact slicing rule is what differs across Types: Type I assigns each term whatever is left over after the previous terms; Type II/III use partial sums that adjust for other terms. The residual is always what is left after every term has had its turn.
Mean square and F-ratio: MS_term = SS_term / df_term MS_resid = SS_resid / df_resid F = MS_term / MS_resid under H0 (term has no effect): F ~ F(df_term, df_resid)
From SS to F. Each term's mean square is its SS scaled by its df. Dividing by the residual MS gives an F-ratio: a value near 1 means the term explains no more than noise; large F means the term explains a lot more than its df budget would predict by chance.
Effect sizes: eta^2_j = SS_j / SS_total partial eta^2_j = SS_j / (SS_j + SS_resid) omega^2_j = (SS_j - df_j * MS_resid) / (SS_total + MS_resid)
Why eta-squared. p-values rank terms by improbability under the null but say nothing about how big the effect is. Eta-squared answers "what fraction of total variance does this term carry?", and partial eta-squared answers "of the variance not already explained by other terms, what fraction does this term carry?". Omega-squared is a less biased version that subtracts the expected SS under the null.
Type I vs II vs III when unbalanced: Type I: SS(A), SS(B|A), SS(A:B|A,B) Type II: SS(A|B), SS(B|A), SS(A:B|A,B) Type III: SS(A|B,A:B), SS(B|A,A:B), SS(A:B|A,B)
The Type triad. All three reduce to the same answer when the design is balanced (equal cell counts and no missing combinations). When unbalanced, Type I depends on the order you typed the terms; Type II tests main effects in a model without their interaction; Type III tests every term holding all others fixed (including interactions) and is what most reporting guidelines now recommend.
Model R-squared: R^2 = 1 - SS_resid / SS_total adj R^2 = 1 - (SS_resid / df_resid) / (SS_total / (n - 1))
Whole-model fit. R-squared from an ANOVA table is the same quantity you would read off summary(lm()): one minus the residual share. Adjusted R-squared penalizes the parameter count. Both fall out of the table because the table already partitions the total variance.
Caveats When this is the wrong tool
If you have…
Use instead
A continuous outcome with no factors
Use the lm() output interpreter. ANOVA tables are most informative when at least one predictor is categorical with more than two levels.
A binary or count outcome
Use the glm() output interpreter (logistic / Poisson). The F-test in this tool assumes Gaussian residuals; for non-Gaussian outcomes the deviance-based analog of ANOVA is the right tool.
Repeated measures or clustered data
A repeated-measures ANOVA layout has an Error() stratum. Parsing one stratum at a time works here, but a mixed-effects model is generally a better fit; see the planned mixed-effects builder tool.
Severely unbalanced design with significant interaction
Type III with sum-to-zero contrasts is the right test, but interpret simple effects (emmeans-style) rather than main effects in isolation. The marginal main-effect F is rarely what you want when interaction is real.
Singular or rank-deficient model
Rows with NA F or zero df are a sign the design matrix is rank-deficient. Drop the offending term or refit with a smaller model; this tool reports the symptom but cannot fix it.
FAQ
What is the difference between Type I, Type II, and Type III sum of squares in ANOVA?

Type I (sequential) tests each term after adjusting for terms entered before it, so the answer depends on term order. Type II tests each main effect after the other main effects but ignores interactions. Type III tests each term after every other term, including interactions. R's base aov() defaults to Type I; use car::Anova() for Type II or III, with sum-to-zero contrasts for Type III.

How do I interpret an ANOVA table with a significant interaction term?

When an interaction is significant the main effects are not interpretable on their own, because the effect of one factor depends on the level of the other. Go straight to an interaction plot or estimated marginal means (the emmeans package) and report differences within each combination of levels rather than the marginal main-effect F.

When should I use ANOVA versus a t-test or Kruskal-Wallis?

Use a t-test for two groups, ANOVA for three or more groups with a continuous outcome, and Kruskal-Wallis (non-parametric) when residuals are non-normal or variances are very unequal. ANOVA assumes normality of residuals and homogeneity of variance, so check those with diagnostic plots before reporting.

Where do the F and p-values on this page come from?

They are recomputed, not read off your pasted text. From each row's Sum Sq and Df the tool forms the mean square (SS / df), divides by the residual mean square to get F, then evaluates the exact upper-tail p-value with R's F distribution (pf, the regularized incomplete beta). That is why a pasted < 2.2e-16 becomes a precise number here.

No data leaves your browser · F, p and effect sizes verified against R's pf() and effectsize · Free

Further reading
  • One-way and two-way ANOVA in R - the basic aov() workflow with mtcars and iris.
  • Type I, II, III sums of squares - worked examples of when they coincide and when they do not.
  • Effect sizes for ANOVA - eta-squared, partial eta-squared, omega-squared, and Cohen's f.
  • Post-hoc tests - Tukey HSD, Bonferroni, Scheffe; family-wise error control.
  • Repeated-measures ANOVA - the Error() stratum and sphericity correction.
  • lm() output interpreter - if your predictors are mostly continuous.
  • Effect-size converter - turn eta-squared into Cohen's f, d, or r.

Numerical notes: the parser handles "< 2.2e-16", scientific notation, signif. codes lines, both column orders (aov: Df-SumSq-MeanSq-F-P; car::Anova: SumSq-Df-F-P), and Type III intercept rows. F is recomputed as (SS_term / df_term) / (SS_resid / df_resid) and the p-value as the exact upper tail of R's F distribution (pf), so both are independent of the rounded values in your paste. eta-squared = SS_term / SS_total (SS_total = column sum of every non-intercept SS including residual); partial eta-squared = SS_term / (SS_term + SS_resid); omega-squared and Cohen's f use the standard closed forms, verified against R's effectsize on balanced designs. A negative omega-squared (a term weaker than chance) is shown floored at 0, matching effectsize. Because effect sizes are read from the printed, rounded table, they can differ from a full-precision fit in the last digits; recompute from the model when you need more.