What Is a Two-Way ANOVA Example?
Two-Way ANOVA Example at a Glance
A two-way ANOVA example has one quantitative dependent variable and two categorical independent variables (factors). The analysis tests three things: the main effect of Factor A, the main effect of Factor B, and the interaction between A and B.
Compact example: A researcher measures crop yield (dependent) for three fertilizer types (A, B, C) at two planting densities (Low, High). This is a 3 x 2 factorial design. Two-way ANOVA asks whether fertilizer type, planting density, or their combined interaction explains differences in mean yield.
| Component | Example Value |
|---|---|
| Dependent variable | Crop yield (kg) |
| Factor A | Fertilizer type (A, B, C) |
| Factor B | Planting density (Low, High) |
| Factor A levels | 3 |
| Factor B levels | 2 |
| Design | 3 x 2 factorial |
| Main effects tested | Fertilizer and Planting Density |
| Interaction tested | Fertilizer x Planting Density |
| Significance level | alpha = 0.05 |
| Output per effect | SS, df, MS, F, p-value, effect size |
Example 1: 2 x 2 Design
Study method x environment. Complete step-by-step calculation.
Example 2: Significant Interaction
Effect of one factor reverses across levels of the other.
Example 3: No Interaction
Two significant main effects, parallel interaction plot.
Example 4: Crossover Pattern
Significant interaction, non-significant main effects.
Example 5: 3 x 2 Factorial
Fertilizer x density. Agriculture context.
What Is Two-Way ANOVA?
The three null hypotheses tested are as follows. First, that there is no main effect of Factor A (the group means for Factor A, averaged across all levels of Factor B, are all equal). Second, that there is no main effect of Factor B (the group means for Factor B, averaged across all levels of Factor A, are all equal). Third, that there is no interaction between Factor A and Factor B (the effect of Factor A does not change across levels of Factor B).
Each hypothesis gets its own F-statistic and p-value. You do not need the main effects to be significant for the interaction to be significant, and vice versa.
Two-way ANOVA requires multiple observations per cell (each combination of Factor A and Factor B levels). That structure is called a replicated factorial design. When there is only one observation per cell, a different model applies and the interaction cannot be estimated separately from error. This distinction matters and is covered in the without-replication section below.
Interactive Two-Way ANOVA Calculator
This calculator uses the balanced replicated two-way ANOVA formulas. Every Factor A x Factor B cell must have the same number of observations (n >= 2). For unbalanced data, use R or Python with Type II or Type III sums of squares.
Two-Way ANOVA Calculator
Enter your data below. Each row is one observation. Factor A and Factor B values must be text labels (e.g., "A", "B", "Low", "High"). Y must be a number.
| # | Factor A | Factor B | Y (Dependent) | Del |
|---|
Cell Means and Summary
Two-Way ANOVA Table
Effect Sizes (Partial Eta Squared)
Interaction Plot
Cell means plotted by Factor A level (x-axis) and Factor B level (separate lines). Non-parallel lines suggest a possible interaction; the ANOVA test determines statistical evidence.
Example 1: Complete 2 x 2 Two-Way ANOVA
This example works through every calculation by hand. The dataset is small enough to verify each step, but large enough to produce a meaningful analysis.
Research question: Does study method affect exam scores, and does this depend on study environment?
Factor A: Study Method (Method 1, Method 2) | Factor B: Environment (Quiet, Group) | Dependent variable: Exam score (0 to 100) | n = 4 observations per cell | N = 16 total
Raw data:
| Method | Environment | Scores | |||
|---|---|---|---|---|---|
| Method 1 | Quiet | 70 | 74 | 72 | 68 |
| Method 1 | Group | 65 | 67 | 63 | 61 |
| Method 2 | Quiet | 82 | 78 | 80 | 76 |
| Method 2 | Group | 75 | 73 | 77 | 71 |
Step 1: Cell Means
| Quiet | Group | Marginal Mean (Method) | |
|---|---|---|---|
| Method 1 | 71.0 | 64.0 | 67.5 |
| Method 2 | 79.0 | 74.0 | 76.5 |
| Marginal Mean (Environment) | 75.0 | 69.0 | Grand Mean = 72.0 |
Method 1 Quiet cell mean: (70 + 74 + 72 + 68) / 4 = 284 / 4 = 71.0. Method 1 Group: (65 + 67 + 63 + 61) / 4 = 256 / 4 = 64.0. Method 2 Quiet: (82 + 78 + 80 + 76) / 4 = 316 / 4 = 79.0. Method 2 Group: (75 + 73 + 77 + 71) / 4 = 296 / 4 = 74.0.
Marginal means: Method 1 = (71 + 64) / 2 = 67.5. Method 2 = (79 + 74) / 2 = 76.5. Quiet = (71 + 79) / 2 = 75.0. Group = (64 + 74) / 2 = 69.0. Grand mean = (71 + 64 + 79 + 74) / 4 = 72.0.
Step 2: Degrees of Freedom
a = 2 levels of Factor A (Method), b = 2 levels of Factor B (Environment), n = 4 observations per cell, N = 2 x 2 x 4 = 16.
Step 3: Sum of Squares
All SS calculations below use the balanced replicated factorial formulas. Every observation is denoted y_ijk where i = Factor A level, j = Factor B level, k = replicate index.
SS Factor A (Study Method)
SS_A = n * b * sum[(mean_i. - grand mean)^2] = 4 * 2 * [(67.5 - 72)^2 + (76.5 - 72)^2] = 8 * [20.25 + 20.25] = 8 * 40.5 = 324.0
SS Factor B (Environment)
SS_B = n * a * sum[(mean_.j - grand mean)^2] = 4 * 2 * [(75 - 72)^2 + (69 - 72)^2] = 8 * [9 + 9] = 8 * 18 = 144.0
SS Interaction (Method x Environment)
SS_AB = n * sum[(cell_ij - mean_i. - mean_.j + grand mean)^2]. Cell deviations: (71 - 67.5 - 75 + 72) = 0.5; (64 - 67.5 - 69 + 72) = -0.5; (79 - 76.5 - 75 + 72) = -0.5; (74 - 76.5 - 69 + 72) = 0.5. SS_AB = 4 * [0.25 + 0.25 + 0.25 + 0.25] = 4 * 1.0 = 4.0
SS Error (Within Cells)
Within each cell, compute sum of squared deviations from the cell mean. Cell 1 (M1/Quiet, mean=71): (70-71)^2+(74-71)^2+(72-71)^2+(68-71)^2 = 1+9+1+9 = 20. Cell 2 (M1/Group, mean=64): (65-64)^2+(67-64)^2+(63-64)^2+(61-64)^2 = 1+9+1+9 = 20. Cell 3 (M2/Quiet, mean=79): (82-79)^2+(78-79)^2+(80-79)^2+(76-79)^2 = 9+1+1+9 = 20. Cell 4 (M2/Group, mean=74): (75-74)^2+(73-74)^2+(77-74)^2+(71-74)^2 = 1+1+9+9 = 20. SS_Error = 20+20+20+20 = 80.0
Verification: SS_Total = SS_A + SS_B + SS_AB + SS_Error = 324 + 144 + 4 + 80 = 552.0. Direct calculation of SS_Total (all 16 observations minus grand mean of 72) confirms 552.0. ✓
Step 4: Complete ANOVA Table
| Source | SS | df | MS | F | p-value | Partial eta^2 |
|---|---|---|---|---|---|---|
| Study Method (A) | 324.0 | 1 | 324.0 | 48.60 | < 0.001 | 0.802 |
| Environment (B) | 144.0 | 1 | 144.0 | 21.60 | 0.001 | 0.643 |
| A x B Interaction | 4.0 | 1 | 4.0 | 0.60 | 0.454 | 0.048 |
| Error (Within) | 80.0 | 12 | 6.667 | |||
| Total | 552.0 | 15 |
MS_A = 324/1 = 324.0. MS_B = 144/1 = 144.0. MS_AB = 4/1 = 4.0. MS_Error = 80/12 = 6.667. F_A = 324/6.667 = 48.60. F_B = 144/6.667 = 21.60. F_AB = 4/6.667 = 0.60.
Partial eta squared for A = 324 / (324 + 80) = 0.802. Partial eta squared for B = 144 / (144 + 80) = 0.643. Partial eta squared for A x B = 4 / (4 + 80) = 0.048.
✓ Conclusion: There is strong evidence of a main effect of study method [F(1,12) = 48.60, p < 0.001, partial eta^2 = 0.80]. There is also evidence of a main effect of environment [F(1,12) = 21.60, p = 0.001, partial eta^2 = 0.64]. The interaction between method and environment is not statistically significant [F(1,12) = 0.60, p = 0.454]. Because the interaction is not significant, the two main effects can be interpreted straightforwardly: Method 2 outperforms Method 1 regardless of environment, and Quiet consistently outperforms Group.
Interaction Plot: Study Method x Environment
Approximately parallel lines indicate little visual evidence of interaction. The ANOVA confirms the interaction is not statistically significant (p = 0.454).
Example 2: Significant Interaction Effect
This example constructs a dataset where the effect of teaching method on test scores differs depending on student ability level. Looking at main effects alone would give an incomplete and potentially misleading picture.
Context: An educator tests two teaching methods (Lecture, Project) with students grouped by ability (Standard, Advanced). Dependent variable: unit test score. n = 3 per cell.
| Method | Ability | Scores | Cell Mean | ||
|---|---|---|---|---|---|
| Lecture | Standard | 68 | 70 | 72 | 70.0 |
| Lecture | Advanced | 85 | 88 | 87 | 86.7 |
| Project | Standard | 76 | 78 | 80 | 78.0 |
| Project | Advanced | 80 | 79 | 81 | 80.0 |
Grand mean = (70 + 86.7 + 78 + 80) / 4 = 78.67. Marginal means: Lecture = 78.33, Project = 79.0. Standard = 74.0, Advanced = 83.33.
| Source | SS | df | MS | F | p-value |
|---|---|---|---|---|---|
| Method (A) | 0.83 | 1 | 0.83 | 0.25 | 0.626 |
| Ability (B) | 552.08 | 1 | 552.08 | 166.05 | < 0.001 |
| A x B | 110.08 | 1 | 110.08 | 33.11 | < 0.001 |
| Error | 26.67 | 8 | 3.33 | ||
| Total | 689.67 | 11 |
Interaction Plot: Teaching Method x Student Ability
Non-parallel lines confirm the significant interaction: Lecture benefits Advanced students far more than Standard students, while Project produces more even results across ability levels.
Here the main effect of teaching method is not significant (p = 0.626), yet the interaction is highly significant. Reporting only that "method did not matter" would be wrong. For Standard students, Project outperforms Lecture by 8 points. For Advanced students, Lecture outperforms Project by nearly 7 points. The effect of method depends entirely on which students you're looking at.
✓ Two-way ANOVA found a significant interaction between teaching method and student ability [F(1,8) = 33.11, p < 0.001]. Project-based learning produced higher scores for Standard-ability students, while Lecture produced higher scores for Advanced students. The main effect of teaching method was not significant when averaged across ability groups, but this average conceals the directional reversal. Researchers should interpret the interaction, not the main effect of method in isolation.
Example 3: Two Significant Main Effects, No Significant Interaction
When the interaction is not significant and both main effects are significant, main effect interpretations are more direct. The following manufacturing example illustrates this.
Context: A manufacturing plant tests two machine settings (Low, High) and two material types (Standard, Premium) on production output. n = 3 per cell.
| Standard Material | Premium Material | Marginal Mean | |
|---|---|---|---|
| Low Setting | 40.0 | 50.0 | 45.0 |
| High Setting | 60.0 | 70.0 | 65.0 |
| Marginal Mean | 50.0 | 60.0 | Grand Mean = 55.0 |
The differences are perfectly additive. Switching from Low to High setting adds 20 units regardless of material type. Switching from Standard to Premium adds 10 units regardless of setting. This is exactly what zero interaction looks like.
| Source | SS | df | MS | F | p-value |
|---|---|---|---|---|---|
| Setting (A) | 1200.0 | 1 | 1200.0 | 240.00 | < 0.001 |
| Material (B) | 300.0 | 1 | 300.0 | 60.00 | < 0.001 |
| A x B | 0.0 | 1 | 0.0 | 0.00 | 1.000 |
| Error | 40.0 | 8 | 5.0 | ||
| Total | 1540.0 | 11 |
It means the data did not provide sufficient evidence of an interaction at alpha = 0.05. With a larger sample or smaller error, a small interaction that genuinely exists might become detectable. Non-significance is not proof of no effect.
Example 4: Significant Interaction with Non-Significant Main Effects
This scenario surprises many students: the interaction can be statistically significant even when both main effects are not. It occurs when factor effects reverse direction across levels of the other factor, a pattern called a crossover interaction.
Cell means (illustrative, with n = 4 per cell to estimate error):
| Factor B: Low | Factor B: High | Marginal Mean | |
|---|---|---|---|
| Factor A: Low | 40 | 60 | 50.0 |
| Factor A: High | 60 | 40 | 50.0 |
| Marginal Mean | 50.0 | 50.0 | Grand Mean = 50.0 |
Both marginal means for Factor A are 50.0. Both marginal means for Factor B are 50.0. The grand mean is 50.0. Averaged across everything, neither factor appears to matter. Yet the cell means show a dramatic reversal: when Factor B is Low, Factor A High scores 20 points higher than Factor A Low. When Factor B is High, Factor A Low scores 20 points higher than Factor A High.
Interaction Plot: Crossover Pattern
Crossing lines are a classic sign of a crossover interaction. The main effects, which average across these reversals, wash out to zero. The interaction is the entire story here.
If a researcher ran only one-way ANOVAs on Factor A and Factor B separately, they would conclude neither factor matters. That conclusion is wrong. Both factors matter, but their effects depend on each other. Two-way ANOVA detects this; separate one-way ANOVAs do not.
Example 5: 3 x 2 Factorial Design (Fertilizer x Density)
Research question: Does crop yield depend on fertilizer type, planting density, or their interaction?
Factor A: Fertilizer (A, B, C) | Factor B: Planting Density (Low, High) | n = 4 per cell | N = 3 x 2 x 4 = 24 | Design: 3 x 2 factorial. All data are illustrative.
| Fertilizer | Density | Yield (kg) | Cell Mean | |||
|---|---|---|---|---|---|---|
| A | Low | 42 | 45 | 43 | 46 | 44.0 |
| A | High | 51 | 49 | 52 | 50 | 50.5 |
| B | Low | 47 | 46 | 45 | 48 | 46.5 |
| B | High | 55 | 57 | 53 | 55 | 55.0 |
| C | Low | 38 | 40 | 37 | 41 | 39.0 |
| C | High | 44 | 43 | 45 | 44 | 44.0 |
Cell Means and Marginal Means
| Fertilizer | Low Density | High Density | Marginal Mean |
|---|---|---|---|
| A | 44.0 | 50.5 | 47.25 |
| B | 46.5 | 55.0 | 50.75 |
| C | 39.0 | 44.0 | 41.50 |
| Marginal Mean | 43.17 | 49.83 | Grand Mean = 46.50 |
Degrees of Freedom
a = 3, b = 2, n = 4. df_A = 3 - 1 = 2. df_B = 2 - 1 = 1. df_AB = (3-1)(2-1) = 2. df_Error = 3 x 2 x (4-1) = 18. df_Total = 24 - 1 = 23. Check: 2 + 1 + 2 + 18 = 23. ✓
ANOVA Table
| Source | SS | df | MS | F | p-value | Partial eta^2 |
|---|---|---|---|---|---|---|
| Fertilizer (A) | 391.58 | 2 | 195.79 | 65.26 | < 0.001 | 0.879 |
| Density (B) | 533.38 | 1 | 533.38 | 177.79 | < 0.001 | 0.908 |
| A x B | 7.58 | 2 | 3.79 | 1.26 | 0.306 | 0.123 |
| Error | 54.0 | 18 | 3.0 | |||
| Total | 986.54 | 23 |
✓ Both fertilizer type [F(2,18) = 65.26, p < 0.001] and planting density [F(1,18) = 177.79, p < 0.001] had significant main effects on crop yield. The interaction between fertilizer and density was not significant [F(2,18) = 1.26, p = 0.306], so the density advantage is consistent across fertilizer types. Fertilizer B produced the highest yields on average (50.75 kg), followed by A (47.25 kg) and C (41.50 kg). High density consistently outperformed Low density by approximately 6.7 kg regardless of fertilizer.
Two-Way ANOVA With and Without Replication
| Feature | With Replication | Without Replication |
|---|---|---|
| Observations per cell | 2 or more (n >= 2) | Exactly 1 |
| Interaction estimable? | Yes, separately from error | No (not in the classical model) |
| Error df | ab(n-1) | (a-1)(b-1) used for the test |
| Excel tool | ANOVA: Two-Factor With Replication | ANOVA: Two-Factor Without Replication |
| Typical use | Factorial experiments | Randomized block designs |
When there is only one observation per cell, the classical approach cannot distinguish the interaction from pure random error. The no-replication model is often appropriate for randomized block designs where one factor is a "blocking" variable rather than a treatment factor of primary interest.
No-Replication Example (Randomized Block Structure)
| Block | Treatment 1 | Treatment 2 | Treatment 3 |
|---|---|---|---|
| Block 1 | 12 | 15 | 17 |
| Block 2 | 11 | 14 | 18 |
| Block 3 | 13 | 16 | 19 |
In this structure, the residual after removing block and treatment effects serves as the error term. No separate interaction term can be extracted. Excel's "Two-Factor Without Replication" tool handles this structure. The analysis tests treatment effects after accounting for block-to-block variation, but it assumes no interaction between blocks and treatments.
Balanced vs Unbalanced Designs
A balanced design has the same number of observations in every cell. All five examples above are balanced. The formulas for SS_A, SS_B, and SS_AB simplify considerably in balanced designs and the three effects are orthogonal (statistically independent of each other).
An unbalanced design has different cell counts. This happens in observational studies and when data is lost. In unbalanced designs, the three effects are no longer orthogonal, so different sums-of-squares conventions can give different answers. The choice between Type I, Type II, and Type III SS matters and should be made deliberately based on the research question.
Do not apply the balanced-design formulas shown in this article to unbalanced data. The results will be incorrect. Use R's drop1() with a fitted model, Python's anova_lm(typ=2), or SPSS's Type III sum of squares option.
Sum of Squares and Degree of Freedom Formulas
| Quantity | Formula (Balanced Replicated Design) | Explanation |
|---|---|---|
| SS_A | n*b * sum[(mean_i. - grand mean)^2] | Variation of Factor A marginal means |
| SS_B | n*a * sum[(mean_.j - grand mean)^2] | Variation of Factor B marginal means |
| SS_AB | n * sum[(mean_ij - mean_i. - mean_.j + GM)^2] | Interaction: cell means minus additive prediction |
| SS_Error | sum of within-cell squared deviations from cell mean | Pure random variability within cells |
| SS_Total | SS_A + SS_B + SS_AB + SS_Error | Total variability in all observations |
| df_A | a - 1 | Number of Factor A levels minus one |
| df_B | b - 1 | Number of Factor B levels minus one |
| df_AB | (a-1)(b-1) | Product of marginal dfs |
| df_Error | ab(n-1) | Within-cell df summed across cells |
| df_Total | N - 1 = abn - 1 | Total df |
| MS_effect | SS_effect / df_effect | Mean square for any effect |
| F_effect | MS_effect / MS_Error | F-ratio for testing any effect |
| Partial eta^2 | SS_effect / (SS_effect + SS_Error) | Effect size for each effect |
How to Interpret the Interaction Effect
An interaction exists when the effect of Factor A on the dependent variable changes depending on which level of Factor B you are looking at. The interaction test asks whether the cell means can be explained by the two main effects alone, or whether additional structure is present.
Reading an Interaction Plot
An interaction plot shows Factor A or B on the x-axis, the mean of the dependent variable on the y-axis, and a separate line for each level of the other factor. Three patterns are common.
Approximately parallel lines: The effect of Factor A is similar across all levels of Factor B. Visual parallelism does not guarantee a non-significant interaction test, but it is encouraging evidence.
Non-parallel but non-crossing lines: The effect of Factor A differs in magnitude across levels of Factor B, but the direction is the same. One level of B consistently produces higher values, just by different amounts. The interaction test may or may not be significant.
Crossing lines: The direction of the Factor A effect reverses across levels of Factor B. This is a crossover interaction. The main effects averaged across this reversal can be misleading or meaningless. The interaction is typically the primary finding.
Non-parallel lines in an interaction plot do not prove statistical significance. Small datasets produce wiggly plots by chance. Always rely on the p-value from the F-test for the interaction term to assess statistical evidence.
What to Do When the Interaction Is Significant
Confirm the result and examine the plot
Check the p-value and degrees of freedom. Inspect the interaction plot to understand the nature of the interaction (ordinal vs disordinal/crossover).
Inspect cell means
Look at the 2D table of cell means. Identify which factor-level combinations produce the highest and lowest values, and whether any reversals are present.
Examine simple effects
Simple effects analyse Factor A at each specific level of Factor B, or vice versa. For instance: "effect of fertilizer at Low density" and "effect of fertilizer at High density." These slice the interaction into interpretable pieces.
Adjust for multiple comparisons if needed
If you perform several follow-up tests (e.g., comparing all fertilizer pairs within each density level), apply a correction such as Bonferroni or the Tukey HSD procedure to control the family-wise error rate.
State the conclusion in terms of the interaction
Describe which factor-level combinations differ and in what direction. Avoid summarising only the main effects when a crossover interaction is present.
Post-Hoc Tests After Two-Way ANOVA
The right follow-up analysis depends on which effect is significant and the nature of the research question. There is no single universal rule like "always run Tukey HSD when ANOVA is significant."
When only main effects are significant and the interaction is not, post-hoc comparisons on Factor A marginal means and Factor B marginal means are reasonable. Tukey HSD is appropriate for all pairwise comparisons among levels of a factor when no directional hypothesis was specified in advance.
When the interaction is significant, simple-effects analysis is more informative than overall main-effect comparisons. Compare Factor A levels within each level of Factor B separately. Apply a multiple comparison correction to the full set of follow-up tests, not just within each simple-effects analysis.
Planned comparisons (contrasts specified before data collection) do not require the same correction as unplanned pairwise tests. If your research question was specifically "does fertilizer B outperform fertilizer A at high density?", that planned contrast can be tested directly without a family-wise correction for all other possible pairs.
Assumptions of Two-Way ANOVA
Independent Observations
Each observation in the dataset comes from a different subject or unit. Repeated measurements on the same subject violate this assumption and require a different model.
Approximately Normal Residuals
The residuals from the fitted model should be approximately normally distributed. This is assessed with a Q-Q plot of residuals, not a normality test on the raw data. ANOVA is reasonably robust to this assumption with larger samples.
Homogeneity of Variance
Residual variance should be similar across all cells. Levene's test provides one diagnostic, but residual plots are usually more informative. Welch-type adjustments exist for heterogeneous variances.
Correct Model Specification
The assumed factorial structure (A, B, and A x B) should match the actual design. Treating a confounded observational variable as an experimental factor can produce meaningless results.
One-Way ANOVA vs Two-Way ANOVA
| Feature | One-Way ANOVA | Two-Way ANOVA |
|---|---|---|
| Number of factors | 1 | 2 |
| Dependent variable | Quantitative | Quantitative |
| Main effects tested | 1 | 2 |
| Interaction tested | No | Yes |
| Factor combinations | Levels of one factor | All combinations of both factors |
| Example question | Does fertilizer type affect yield? | Does fertilizer and density interact to affect yield? |
| Can detect crossover? | No | Yes |
| Efficiency | Lower (one effect at a time) | Higher (two effects and interaction) |
| Link on this site | ANOVA guide | Two-way ANOVA guide |
Running two separate one-way ANOVAs instead of one two-way ANOVA has two problems. It inflates the family-wise error rate (two tests at alpha = 0.05 gives a combined false-positive risk above 5%), and it cannot detect whether the factors interact. A factorial design with two-way ANOVA answers both main-effect questions and the interaction question in a single, controlled analysis.
Two-Way ANOVA in R
# Load data frame with columns: method, environment, score # (Replace with your actual data frame) data <- data.frame( method = rep(c("Method1", "Method2"), 8), environment = rep(c("Quiet","Quiet","Quiet","Quiet", "Group","Group","Group","Group"), 2), score = c(70,74,72,68, 82,78,80,76, 65,67,63,61, 75,73,77,71) ) # Fit the two-way ANOVA model with interaction model <- aov(score ~ method * environment, data = data) summary(model) # The formula method * environment expands to: # method + environment + method:environment # Interaction plot interaction.plot(data$method, data$environment, data$score, xlab = "Study Method", ylab = "Mean Score", trace.label = "Environment") # Effect sizes (partial eta squared) # install.packages("effectsize") if needed library(effectsize) eta_squared(model, partial = TRUE) # Post-hoc comparisons (if main effects significant and no interaction) TukeyHSD(model, "method") TukeyHSD(model, "environment")
Two-Way ANOVA in Python
import pandas as pd import statsmodels.api as sm from statsmodels.formula.api import ols import matplotlib.pyplot as plt # Build the data frame df = pd.DataFrame({ 'method': ['M1']*4 + ['M2']*4 + ['M1']*4 + ['M2']*4, 'env': ['Quiet']*8 + ['Group']*8, 'score': [70,74,72,68, 82,78,80,76, 65,67,63,61, 75,73,77,71] }) # Fit the model: C() tells statsmodels these are categorical variables model = ols('score ~ C(method) * C(env)', data=df).fit() # Type II SS is appropriate for balanced designs (default for main effects) # Use typ=3 for Type III SS (requires effects coding / sum coding) anova_table = sm.stats.anova_lm(model, typ=2) print(anova_table) # Interaction plot means = df.groupby(['method', 'env'])['score'].mean().reset_index() for env, grp in means.groupby('env'): plt.plot(grp['method'], grp['score'], marker='o', label=env) plt.ylabel('Mean Score') plt.legend(title='Environment') plt.title('Interaction Plot') plt.show()
For balanced designs, Type II and Type III SS give the same answer. For unbalanced data, they can differ. Type II tests each main effect while holding other main effects constant but ignoring interactions. Type III tests each effect while holding all other terms constant, but requires sum-to-zero coding to be interpretable. Neither is universally correct; the choice depends on your design and research question.
Two-Way ANOVA in Excel
Excel's Data Analysis ToolPak includes two two-way ANOVA procedures. Go to Data > Data Analysis to find them.
ANOVA: Two-Factor With Replication
Use this when you have multiple observations per cell. Arrange your data with Factor A categories as column headers and Factor B categories as row labels (or use a stacked layout). In the dialog, specify the number of rows per sample (this is n, the number of replicates per cell). Excel reports SS, df, MS, F, P-value, and F critical for Factor A, Factor B, and the interaction.
ANOVA: Two-Factor Without Replication
Use this for a one-observation-per-cell structure such as a randomized block design. This procedure cannot estimate an interaction term. If your data has multiple observations per cell, do not use this option; the results will be misleading.
| Software | Method | SS Type |
|---|---|---|
| Excel | Data Analysis > ANOVA: Two-Factor With Replication | Balanced Type I by default |
| R | aov(y ~ factorA * factorB) | Type I; use drop1() for Type II |
| Python | ols() + anova_lm(typ=2) | Specify typ=2 or typ=3 |
| SPSS | Analyze > General Linear Model > Univariate | Type III by default |
Effect Size in Two-Way ANOVA
Statistical significance tells you whether an effect likely exists given the sample size. Effect size tells you how large that effect is, independently of sample size. Both are needed for a complete analysis.
Partial eta squared (partial eta^2) is the most common effect size for two-way ANOVA. For each effect, it is SS_effect / (SS_effect + SS_Error). It answers the question: what proportion of the variability in the outcome, that is not explained by other effects in the model, is explained by this one effect? Partial eta^2 ranges from 0 to 1 and is always tied to the specific model you fitted.
Eta squared (eta^2) is SS_effect / SS_Total. It is a less common choice in factorial designs because SS_Total changes depending on which effects are in the model, making comparisons across studies difficult.
Common reference points from the literature treat partial eta^2 of 0.01 as small, 0.06 as medium, and 0.14 as large, but these benchmarks are rough conventions from a specific context and should not be applied mechanically across all research fields.
Common Two-Way ANOVA Mistakes
| # | Mistake | What to Do Instead |
|---|---|---|
| 1 | Interpreting main effects in isolation when the interaction is significant | Examine simple effects and the interaction plot first |
| 2 | Applying balanced-design SS formulas to unbalanced data | Use GLM with Type II or III SS in R, Python, or SPSS |
| 3 | Treating one observation per cell as replicated data | Use the without-replication model or collect more data |
| 4 | Concluding no effect when p >= 0.05 | State "insufficient evidence," report effect size and confidence intervals |
| 5 | Using two one-way ANOVAs instead of one two-way ANOVA | Use two-way ANOVA to test both factors and their interaction together |
| 6 | Confusing repeated measures with independent factorial design | Use repeated measures ANOVA or mixed-effects model for dependent observations |
| 7 | Assuming non-parallel lines in the plot prove a significant interaction | Always rely on the F-test for the interaction term |
| 8 | Assuming parallel lines in the plot prove no interaction | Small sample sizes produce noisy plots; the test can still detect interactions |
| 9 | Running all pairwise post-hoc comparisons regardless of which effects were significant | Design follow-up tests to match the pattern of significant effects |
| 10 | Reporting only p-values without effect sizes | Report F, df, p, and partial eta^2 for each effect |
How to Report a Two-Way ANOVA
A complete APA-style report includes the F-statistic, numerator and denominator degrees of freedom, p-value, and effect size for each effect. Below is a template using values from Example 1.
Reporting Template
Example Results Section
"A two-way ANOVA examined the effects of study method (Method 1, Method 2) and study environment (Quiet, Group) on exam scores. There was a significant main effect of study method [F(1, 12) = 48.60, p < .001, partial eta^2 = .80], with Method 2 producing higher scores (M = 76.5) than Method 1 (M = 67.5). There was also a significant main effect of environment [F(1, 12) = 21.60, p = .001, partial eta^2 = .64], with Quiet environments producing higher scores (M = 75.0) than Group environments (M = 69.0). The interaction between study method and environment was not statistically significant [F(1, 12) = 0.60, p = .454, partial eta^2 = .05], indicating that the advantage of Method 2 was consistent across both environment types."
Practice Problems
A study measures blood pressure after three drug doses (Low, Medium, High) for two patient age groups (Under 50, Over 50). Identify the dependent variable, Factor A, Factor B, and the factorial design notation.
In a two-way ANOVA with a = 3 Factor A levels, b = 4 Factor B levels, and n = 5 observations per cell, calculate all degrees of freedom and verify they sum to df_Total.
A two-way ANOVA gives: SS_A = 120, SS_B = 60, SS_AB = 30, SS_Error = 90. N = 36. MS_Error = 5. Calculate F for each effect and determine which are significant at alpha = 0.05 given df_A = 2, df_B = 1, df_AB = 2, df_Error = 18.
A researcher finds significant Factor A and Factor B main effects, plus a significant A x B interaction. A colleague says "just report that both main effects are significant." Why is this advice potentially misleading?
A balanced 2 x 3 design has n = 5 per cell. A researcher computes SS_Total = 400, SS_A = 80, SS_B = 150, SS_AB = 20. Calculate SS_Error and verify the decomposition.
A dataset has 2 Factor A levels, 3 Factor B levels, and only 1 observation per cell (N = 6 total). Is the standard balanced replicated two-way ANOVA appropriate? What model is more suitable?
Sample Dataset
The CSV below matches Example 5 (Fertilizer x Density). Copy it into a spreadsheet or paste it into the calculator above using the "Load 3 x 2 Example" button.
Fertilizer,Density,Yield A,Low,42 A,Low,45 A,Low,43 A,Low,46 A,High,51 A,High,49 A,High,52 A,High,50 B,Low,47 B,Low,46 B,Low,45 B,Low,48 B,High,55 B,High,57 B,High,53 B,High,55 C,Low,38 C,Low,40 C,Low,37 C,Low,41 C,High,44 C,High,43 C,High,45 C,High,44
Frequently Asked Questions
A two-way ANOVA example has one quantitative dependent variable and two categorical factors. A typical example: you measure crop yield for three fertilizer types (A, B, C) at two planting densities (Low, High). Two-way ANOVA tests whether fertilizer type affects yield, whether density affects yield, and whether fertilizer and density interact to affect yield differently than either factor alone would predict.
H0(A): The main effect of Factor A is zero (all Factor A marginal means are equal). H0(B): The main effect of Factor B is zero (all Factor B marginal means are equal). H0(AB): The interaction between Factor A and Factor B is zero (the effect of Factor A is the same at every level of Factor B). Each hypothesis has its own F-statistic, degrees of freedom, and p-value.
A significant interaction means the effect of Factor A on the dependent variable differs across levels of Factor B (and vice versa). For instance, if fertilizer B produces much higher yields at low density but barely outperforms fertilizer A at high density, the two factors interact. When the interaction is significant, main effects should not be interpreted in isolation because their meaning depends on which level of the other factor you are looking at.
Yes, this is the crossover case shown in Example 4. When the effect of Factor A is positive at one level of Factor B and negative at another, the two effects cancel when averaged, producing a marginal mean difference near zero. The main effect F-test then shows no significance, even though Factor A clearly matters. This is one reason to always check the interaction before interpreting the main effects.
Two-way ANOVA with replication means there are multiple observations within each cell (each combination of Factor A level and Factor B level). For example, measuring yield for 4 plots per fertilizer-density combination. With n ≥ 2 per cell, you can estimate the interaction separately from random error. Without replication (n = 1 per cell), the interaction and error are confounded and cannot both be estimated.
One-way ANOVA tests whether one categorical factor affects a quantitative outcome. Two-way ANOVA tests two categorical factors simultaneously and additionally tests whether they interact. Two-way ANOVA is more statistically efficient (it tests two questions with one dataset) and can detect effects that separate one-way tests would miss, particularly crossover interactions.
Each F-statistic is the mean square for that effect divided by the mean square for error. F_A = MS_A / MS_Error. F_B = MS_B / MS_Error. F_AB = MS_AB / MS_Error. Each mean square is its sum of squares divided by its degrees of freedom. MS_Error = SS_Error / [ab(n-1)] for a balanced replicated design. The F-statistics are compared to the F-distribution with the appropriate numerator and denominator degrees of freedom.
The standard assumptions are: (1) observations are independent of each other; (2) residuals from the fitted model are approximately normally distributed; (3) residual variance is roughly equal across all cells (homogeneity of variance); (4) the model correctly specifies the factors and their interaction. These are assumptions about the residuals and the design, not simply about whether the raw data look normal.
Tukey HSD is appropriate for all pairwise comparisons among levels of a factor when no hypotheses were specified before data collection. Use it for main-effect comparisons when the interaction is not significant (or is ordinal and does not invalidate the marginal comparison). When the interaction is significant, simple-effects analysis is usually more informative than comparing marginal means. Apply Tukey HSD within each simple-effect analysis if you are making multiple pairwise comparisons.
In Excel, go to Data > Data Analysis > ANOVA: Two-Factor With Replication. Arrange your data with Factor B categories as column headers and Factor A groups in consecutive rows, with n rows per group. In the dialog, set "Rows per sample" to n (your replication count). Excel reports SS, df, MS, F, P-value, and F critical for Factor A (rows), Factor B (columns), and the interaction. For a no-replication design, use ANOVA: Two-Factor Without Replication instead.
Yes, but not with the simple balanced-design formulas. Unbalanced two-way ANOVA requires a general linear model approach where the choice of Type I, II, or III sums of squares changes the result. Statistical software such as R, Python (statsmodels), or SPSS handles unbalanced designs correctly. Do not use the balanced formulas shown in this article for unbalanced data.