ANOVA vs Regression: The One-Paragraph Answer
What Is ANOVA?
ANOVA stands for Analysis of Variance. It tests whether the means of three or more groups are equal — the null hypothesis is always H₀: μ₁ = μ₂ = ... = μₖ. It was developed by Ronald Fisher in the 1920s and remains one of the most widely used tests in experimental research.
The core idea is a ratio. ANOVA partitions the total variability in your data into two components: variance that comes from differences between groups (between-group variance) and variance that comes from differences within each group (within-group variance, or error). If the groups truly have the same mean, the between-group variance should be roughly the same size as the within-group variance — so the F-ratio should be close to 1. When the F-ratio is large, the between-group differences are hard to explain by chance alone.
MSBetween = SSBetween / dfBetween
MSWithin = SSWithin / dfWithin
dfBetween = k − 1
dfWithin = N − k
Where k is the number of groups and N is the total sample size. The F-statistic follows an F-distribution under H₀. A statistically significant F-test (p < α) tells you that at least one group mean differs from the others — it does not tell you which pairs differ. For that, you run a post-hoc test such as Tukey's HSD.
Types of ANOVA
| Type | Independent Variables | When to Use |
|---|---|---|
| One-Way ANOVA | 1 categorical IV | Compare 3+ group means on one factor (e.g., 3 fertilizer types → crop yield) |
| Two-Way ANOVA | 2 categorical IVs | Test main effects of two factors and their interaction (e.g., drug × dosage) |
| Repeated Measures ANOVA | 1 within-subjects IV | Same subjects measured across time or conditions (pre/post/follow-up) |
| ANCOVA | 1+ categorical + 1+ continuous | Compare group means while controlling for a continuous covariate |
| MANOVA | 1+ categorical IVs | Multiple continuous dependent variables simultaneously |
What Is Regression?
Regression models the relationship between one or more independent variables (predictors) and a continuous dependent variable (outcome). The simplest form is simple linear regression, which fits a straight line through the data to minimize the sum of squared residuals — a method called Ordinary Least Squares (OLS).
Ŷ = predicted Y
β₀ = intercept
β₁ = slope (regression coefficient)
X = predictor variable
ε = residual error
Multiple regression extends this to two or more predictors: Ŷ = β₀ + β₁X₁ + β₂X₂ + ... + βₚXₚ + ε. The regression coefficients β₁, β₂, ... βₚ represent the expected change in Y for a one-unit increase in the corresponding predictor, holding all other predictors constant. This "holding constant" property is what makes regression more powerful than ANOVA for observational data with confounders.
The F-test in regression tests whether the overall model explains a statistically significant proportion of variance in Y. The model's explanatory power is summarized by R² — the proportion of variance in Y accounted for by the predictors. Learn more in the R-squared guide and the full simple linear regression tutorial.
Types of Regression
| Type | Outcome Variable | When to Use |
|---|---|---|
| Simple Linear Regression | Continuous | One continuous predictor → one continuous outcome (Y = β₀ + β₁X) |
| Multiple Linear Regression | Continuous | Two or more predictors (continuous, categorical, or mixed) → continuous outcome |
| Logistic Regression | Binary (0/1) | Predict probability of a binary outcome (disease/no disease, churn/no churn) |
| Polynomial Regression | Continuous | Non-linear relationship between X and Y (adds X², X³ terms) |
| Ridge / Lasso | Continuous | High-dimensional data; prevents overfitting via regularization |
Key Differences Between ANOVA and Regression
The central difference: ANOVA requires a categorical independent variable and tests whether group means differ. Regression accepts continuous (or categorical, via dummy variables) independent variables and models the quantitative relationship between predictors and an outcome. ANOVA asks "do means differ?" Regression asks "how much does Y change when X changes?"
| Dimension | ANOVA | Regression |
|---|---|---|
| Primary purpose | Compare group means | Model relationship; predict outcome |
| Independent variable type | Categorical (nominal or ordinal) | Continuous, categorical (dummy-coded), or mixed |
| Dependent variable type | Continuous | Continuous (linear); binary (logistic) |
| Research question | "Do these k groups have different means?" | "How does Y change with X?" or "What is the predicted Y?" |
| Output | F-statistic, p-value, group means, effect size (η²) | Regression coefficients (β), R², F-statistic, p-value per predictor |
| Prediction equation | No (gives group means only) | Yes (Ŷ = β₀ + β₁X₁ + ...) |
| Number of predictors | Typically 1–2 categorical factors | Scales to many predictors easily |
| Categorical variables | Treated directly as grouping factors | Encoded as k−1 dummy variables |
| Handles continuous predictors | No (they become ANCOVA) | Yes |
| Interaction effects | Yes — two-way ANOVA | Yes — product terms (X₁ × X₂) |
| Test statistic | F | F (overall model); t (per coefficient) |
| Historical use | Experimental designs, clinical trials | Observational studies, prediction, forecasting |
How ANOVA and Regression Are Related
ANOVA and regression look different on the surface, but they are mathematically identical when run on the same data. Both are special cases of the General Linear Model (GLM). This is one of the most important facts in applied statistics — and one of the most commonly overlooked.
The General Linear Model Connection
Why ANOVA Is Regression With Dummy Variables
Consider one-way ANOVA with three groups (A, B, C). Create two dummy variables: D₁ = 1 if group B (else 0), D₂ = 1 if group C (else 0). Group A serves as the reference category. Now run the regression: Ŷ = β₀ + β₁D₁ + β₂D₂. The resulting F-statistic, p-value, and R² are numerically identical to those from the one-way ANOVA. β₀ is the mean of group A. β₀ + β₁ is the mean of group B. β₀ + β₂ is the mean of group C. The regression framework adds the bonus of showing whether each group differs from the reference, and by exactly how much.
β₀ = mean of reference group (Group A)
β₁ = Group B mean − Group A mean
β₂ = Group C mean − Group A mean
- Both use the F-test to assess whether the model explains a significant portion of variance
- Both use Ordinary Least Squares (OLS) to estimate model parameters
- Both report R² (proportion of variance explained)
- Both assume normality of residuals, independence, and homoscedasticity
- Both are special cases of the GLM — software like R, SPSS, and SAS implement them through the same computational engine
- Both test hypothesis H₀: the model provides no improvement over predicting every observation with the grand mean
Decision Tree: Which Method Should You Use?
Answer these four questions in order. Each one narrows the choice:
ANOVA vs Regression Decision Tree
Assumptions: ANOVA vs Regression
Both methods share the same three core assumptions because both are implementations of the General Linear Model. When an assumption is violated, the consequences are similar for both methods.
- Independence: observations within and across groups are independent
- Normality: residuals (or the DV within each group) are approximately normally distributed
- Homoscedasticity: variance within each group is approximately equal (Levene's test checks this)
- Random sampling or random assignment to groups
- The DV is measured on an interval or ratio scale
- Independence: observations are independent
- Normality of residuals: residuals are approximately normally distributed (check with QQ plot)
- Homoscedasticity: variance of residuals is constant across all values of X
- Linearity: the relationship between each predictor and Y is linear
- No perfect multicollinearity (for multiple regression: predictors are not exact linear combinations of each other)
If normality is violated with large samples (n > 30 per group), both methods are generally robust due to the Central Limit Theorem. If homoscedasticity is violated, use Welch's ANOVA (for ANOVA) or heteroscedasticity-robust standard errors (for regression). If independence is violated, neither method is valid without modification — consider mixed models or GEE. Learn more about normality tests and checking statistical assumptions.
Worked Examples
Example 1 — One-Way ANOVA: Teaching Methods and Exam Scores
A school district tests three teaching methods (Traditional, Flipped Classroom, Project-Based Learning) on 15 students each. The outcome is a standardized exam score (0–100).
| Teaching Method | n | Mean Score (x̄) | SD |
|---|---|---|---|
| Traditional (Group A) | 15 | 72.4 | 8.3 |
| Flipped Classroom (Group B) | 15 | 79.1 | 7.6 |
| Project-Based (Group C) | 15 | 83.7 | 9.1 |
| Grand Mean | 45 | 78.4 | — |
Do the three teaching methods produce different mean exam scores? (α = 0.05)
Hypotheses: H₀: μ_A = μ_B = μ_C (all teaching methods produce the same mean score) | H₁: At least one mean differs
Calculate SS Between: SS_Between = Σ nⱼ(x̄ⱼ − grand mean)² = 15(72.4−78.4)² + 15(79.1−78.4)² + 15(83.7−78.4)² = 15(36) + 15(0.49) + 15(28.09) = 540 + 7.35 + 421.35 = 968.7
Degrees of freedom: df_Between = k − 1 = 3 − 1 = 2 | df_Within = N − k = 45 − 3 = 42
MS Between: MS_Between = 968.7 / 2 = 484.35 | MS_Within (pooled within-group variance using the SDs above) ≈ 69.6
F statistic: F = MS_Between / MS_Within = 484.35 / 69.6 = F(2, 42) = 6.96
Decision: The critical F-value at α = 0.05 with df = (2, 42) is 3.22 (from the F-table). F = 6.96 > 3.22, so p < 0.05.
✅ Conclusion: Reject H₀. At α = 0.05, there is significant evidence that teaching method affects exam scores (F(2,42) = 6.96, p < 0.05). A post-hoc test (Tukey's HSD) would identify which specific pairs differ. Project-Based Learning (x̄ = 83.7) outperforms Traditional (x̄ = 72.4) by 11.3 points — an educationally meaningful gap.
Example 2 — Simple Linear Regression: House Prices
A real estate analyst wants to predict house prices from square footage. She collects data on 20 houses.
Data summary: x̄ (sq ft) = 1,850, ȳ (price) = $285,000, Σ(X−x̄)² = 4,200,000, Σ(X−x̄)(Y−ȳ) = 504,000,000
Calculate the slope (β₁): β₁ = Σ(X−x̄)(Y−ȳ) / Σ(X−x̄)² = 504,000,000 / 4,200,000 = $120 per sq ft
Calculate the intercept (β₀): β₀ = ȳ − β₁x̄ = 285,000 − 120 × 1,850 = 285,000 − 222,000 = $63,000
Regression equation: Ŷ = 63,000 + 120 × X
Prediction: For a 2,200 sq ft house: Ŷ = 63,000 + 120(2,200) = 63,000 + 264,000 = $327,000
Interpretation: Each additional square foot is associated with a $120 increase in price, holding all else constant. The intercept ($63,000) is the estimated price of a house with zero square feet — not directly meaningful, but necessary for the equation.
✅ Why regression and not ANOVA: Square footage is a continuous predictor. ANOVA would require binning sq ft into arbitrary categories (small/medium/large), losing information. Regression uses the full continuous range and produces a prediction equation. See the full slope and intercept guide.
Example 3 — ANOVA vs Regression in a Clinical Trial
Case Study — Healthcare Research
Blood Pressure: Three Drug Groups vs Continuous Dosage
Scenario A (Use ANOVA): A pharmaceutical company tests Drug A, Drug B, and Placebo in a randomized controlled trial. 30 patients per group. Outcome: systolic blood pressure at 12 weeks. The predictor is treatment group (categorical: A / B / Placebo). Goal: determine whether any treatment reduces BP compared to placebo. Correct choice: one-way ANOVA, followed by Dunnett's test to compare each drug to placebo.
Scenario B (Use Regression): The same company now studies whether dosage (mg/day, ranging 10–80 mg continuously) predicts BP reduction. The predictor is now continuous. Goal: estimate how much each additional mg reduces BP and determine the optimal dose. Correct choice: simple linear regression (or polynomial regression if the dose-response curve is non-linear).
Using Categorical Variables in Regression: Dummy Coding
When you want to include a categorical variable in a regression model, you convert it into dummy variables (also called indicator variables). For a variable with k categories, you create k−1 dummy variables. The omitted category becomes the reference group.
Teaching Method (3 groups: Traditional, Flipped, Project-Based) → 2 dummy variables
| Teaching Method | D₁ (Flipped = 1) | D₂ (Project = 1) |
|---|---|---|
| Traditional (reference) | 0 | 0 |
| Flipped Classroom | 1 | 0 |
| Project-Based Learning | 0 | 1 |
Resulting regression: Score = β₀ + β₁D₁ + β₂D₂. Here β₀ = 72.4 (Traditional mean), β₁ = 6.7 (Flipped − Traditional), β₂ = 11.3 (Project − Traditional). The F-statistic is identical to the ANOVA F-statistic. But the regression output gives you the magnitude of each group difference, which ANOVA alone does not.
Software Implementation: R, Python, and SPSS
R Code
# Create data teaching <- data.frame( method = rep(c("Traditional", "Flipped", "Project"), each = 15), score = c(rnorm(15, 72.4, 8.3), rnorm(15, 79.1, 7.6), rnorm(15, 83.7, 9.1)) ) # One-Way ANOVA anova_model <- aov(score ~ method, data = teaching) summary(anova_model) # Post-hoc test TukeyHSD(anova_model) # Equivalent regression with dummy variables # R creates dummies automatically; Traditional becomes reference teaching$method <- relevel(factor(teaching$method), ref = "Traditional") reg_model <- lm(score ~ method, data = teaching) summary(reg_model) # F-statistic in lm() output == F-statistic in aov() output # Simple linear regression (continuous predictor) houses <- data.frame(sqft = c(1200,1500,2000,2500,3000), price = c(207000,243000,303000,363000,423000)) lm(price ~ sqft, data = houses) |> summary()
Python Code
import numpy as np import pandas as pd from scipy import stats import statsmodels.api as sm from statsmodels.formula.api import ols # --- One-Way ANOVA --- traditional = np.array([68, 74, 71, 76, 70, 73, 69, 75, 72, 78, 66, 80, 71, 73, 70]) flipped = np.array([75, 82, 78, 80, 77, 84, 79, 76, 81, 83, 74, 79, 80, 82, 76]) project = np.array([80, 87, 84, 86, 82, 89, 85, 79, 88, 83, 81, 86, 84, 85, 87]) F, p = stats.f_oneway(traditional, flipped, project) print(f"F = {F:.3f}, p = {p:.4f}") # --- Equivalent regression with dummies (statsmodels) --- df = pd.DataFrame({ 'score': np.concatenate([traditional, flipped, project]), 'method': ['Traditional']*15 + ['Flipped']*15 + ['Project']*15 }) model = ols('score ~ C(method, Treatment(reference="Traditional"))', data=df).fit() print(model.summary()) # --- Simple linear regression --- sqft = np.array([1200, 1500, 2000, 2500, 3000]) price = np.array([207000, 243000, 303000, 363000, 423000]) slope, intercept, r, p, se = stats.linregress(sqft, price) print(f"β₁={slope:.1f}, β₀={intercept:.0f}, R²={r**2:.4f}")
ANOVA vs Regression vs Related Methods
ANOVA vs ANCOVA
| Dimension | ANOVA | ANCOVA |
|---|---|---|
| Predictors | Categorical only | Categorical + at least one continuous covariate |
| Purpose | Compare group means | Compare group means after controlling for the covariate |
| Power | Lower if covariate is correlated with DV | Higher — covariate reduces within-group error variance |
| Example | 3 drugs → BP | 3 drugs → BP, controlling for baseline BP |
ANOVA vs MANOVA
| Dimension | ANOVA | MANOVA |
|---|---|---|
| Dependent variables | One continuous DV | Two or more continuous DVs simultaneously |
| Type I error | Well-controlled | MANOVA controls Type I error better than running multiple ANOVAs |
| Example | 3 teaching methods → exam score | 3 teaching methods → exam score AND attendance AND engagement |
Regression vs Correlation
| Dimension | Correlation (Pearson r) | Linear Regression |
|---|---|---|
| Purpose | Measure strength and direction of linear association | Model the relationship; predict Y from X |
| Output | r (−1 to +1) and R² = r² | β₀, β₁, R², F-statistic, prediction equation |
| Direction | Symmetric — r(X, Y) = r(Y, X) | Asymmetric — X predicts Y, not vice versa |
| Relationship | r² = R² in simple linear regression | Uses r to compute β₁ = r × (sy/sx) |
Learn more about the relationship between these measures in the Pearson correlation guide and the scatter plots and correlation tutorial.
Linear Regression vs Logistic Regression
| Dimension | Linear Regression | Logistic Regression |
|---|---|---|
| Outcome variable | Continuous (e.g., blood pressure, price) | Binary (e.g., disease/no disease, churn/no churn) |
| Output | Predicted Y value | Predicted probability P(Y = 1) |
| Link function | Identity (direct) | Logit (log-odds) |
| Example | Dosage → BP reduction (continuous) | Dosage → disease probability (binary) |
See the logistic regression guide for a full treatment of binary outcomes.
The SELECT Framework: Choosing Any Statistical Test
Here is a structured approach for choosing between ANOVA, regression, or any other method. Work through all six steps before running any analysis.
Specify the Research Question
Write it out in one sentence. Does it ask about differences between groups? (→ ANOVA direction) Or about the size of a relationship or a predicted value? (→ regression direction) This single sentence should contain your outcome variable, your predictor, and your goal.
Examine Variable Types
Identify every variable as continuous, ordinal, or nominal/categorical. Continuous predictor → regression. Categorical predictor, continuous outcome → ANOVA or regression with dummies. Binary outcome → logistic regression. Categorical outcome → chi-square or log-linear models.
List the Assumptions
Write down the assumptions of each candidate method and check whether your data satisfies them. Run Shapiro-Wilk for normality, Levene's test for equal variances. If a key assumption fails, either transform the data or switch to a non-parametric alternative (Kruskal-Wallis for ANOVA, rank-based methods for regression).
Evaluate the Objective
Is the goal description (compare means), explanation (estimate coefficients), or prediction (produce Ŷ for new X)? Description → ANOVA is cleaner. Prediction → regression gives you the equation. Explanation with multiple mixed predictors → multiple regression.
Choose the Appropriate Model
Using the information from steps S, E, L, and E: select the most appropriate method. When in genuine doubt between ANOVA and regression, run the regression with dummy variables — it gives you everything ANOVA gives you, plus the coefficient estimates and a prediction equation.
Test and Interpret Results
Run the model. Report F, p, and effect size (η² for ANOVA; R² and β for regression). Write a plain-language conclusion tied back to the research question. For ANOVA: "At least one group mean differs (F(df1,df2) = X, p = Y)." For regression: "A one-unit increase in X is associated with a β₁-unit change in Y (β₁ = X, t = Y, p = Z, R² = W)."
Original Dataset: Marketing Campaign Performance
The following original dataset illustrates when ANOVA and regression each apply to the same business scenario. The data records sales revenue across five advertising channels and by advertising spend.
| Channel | Spend ($000) | Revenue ($000) | n Campaigns | Mean Revenue |
|---|---|---|---|---|
| TV | 50 | 210 | 12 | $198k |
| Social Media | 30 | 175 | 18 | $163k |
| 8 | 95 | 20 | $88k | |
| Search (PPC) | 25 | 160 | 15 | $153k |
| 15 | 72 | 10 | $68k |
Run one-way ANOVA with Channel (5 groups) as the IV and Revenue as the DV. This tests whether mean revenue differs across channels. It answers: "Which advertising channels perform significantly differently from each other?" Post-hoc Tukey HSD would then show that TV and Social Media are not significantly different from each other, but both significantly outperform Print and Email.
Run simple linear regression with Spend as X and Revenue as Y. This answers: "How much additional revenue does each additional $1,000 in ad spend generate?" The regression equation (e.g., Revenue = 40 + 3.4 × Spend) allows prediction of revenue for any given budget — something ANOVA cannot do. Regression is the correct tool when the predictor is continuous spend, not categorical channel.
Common Mistakes When Choosing Between ANOVA and Regression
| Mistake | Wrong Approach | Correct Approach |
|---|---|---|
| Binning a continuous predictor to use ANOVA | Converting age (continuous) into "young/middle/old" groups to run ANOVA | Use regression with age as a continuous predictor. Binning loses information and reduces power. |
| Running multiple t-tests instead of ANOVA | Running 3 t-tests to compare 3 groups pairwise (inflates Type I error) | Run one-way ANOVA. If significant, use a post-hoc test (Tukey's HSD) that controls family-wise error rate. |
| Treating ANOVA and regression as incompatible | Assuming you must choose one and can never use the other | They are mathematically equivalent. If in doubt, use regression with dummy variables — it gives you everything ANOVA gives, plus more. |
| Ignoring the interaction in two-way ANOVA | Interpreting main effects in two-way ANOVA without checking the interaction term | Always check the interaction F-test first. A significant interaction means main effects cannot be interpreted independently. |
| Using R² from ANOVA instead of η² | Reporting R² from regression software when running an ANOVA-type model | Report η² (eta-squared) = SS_Between / SS_Total for ANOVA effect size. It has the same formula as R² but has a different interpretive context. |
Entity and Formula Glossary
| Term | Formula / Symbol | Definition |
|---|---|---|
| ANOVA | F = MS_B / MS_W | Analysis of Variance. Tests equality of means across k ≥ 3 groups using the F-test. |
| Linear Regression | Ŷ = β₀ + β₁X + ε | Models the linear relationship between a continuous predictor and a continuous outcome. |
| Multiple Regression | Ŷ = β₀ + Σβⱼ Xⱼ | Extends linear regression to two or more predictors (continuous or dummy-coded). |
| F-statistic | F = MS_Between / MS_Within | Ratio of explained variance to unexplained variance. Same statistic in both ANOVA and regression. |
| R² | R² = SS_Regression / SS_Total | Proportion of variance in Y explained by the model. Ranges 0–1. |
| Regression Coefficient | β₁ = Σ(X−x̄)(Y−ȳ) / Σ(X−x̄)² | Expected change in Y per one-unit increase in X, holding other predictors constant. |
| Residual | eᵢ = Yᵢ − Ŷᵢ | Difference between the observed value and the model's predicted value. |
| Dummy Variable | D = 0 or 1 | Binary indicator that encodes categorical group membership for use in regression. |
| ANCOVA | Ŷ = β₀ + β_group + β_cov·X | Combines ANOVA with a continuous covariate to increase precision and control for confounding. |
| MANOVA | Wilks' Λ | Multivariate ANOVA. Tests group differences on two or more continuous DVs simultaneously. |
| η² (Eta-squared) | η² = SS_Between / SS_Total | ANOVA effect size. Numerically identical to R² in simple regression with one categorical predictor. |
| GLM | Y = Xβ + ε | General Linear Model. Unifying framework for ANOVA, regression, ANCOVA, and MANOVA. |
| p-value | P(F ≥ F_obs | H₀) | Probability of observing the data if H₀ is true. Reject H₀ when p < α. |
| Effect size | η² or Cohen's f | Standardized measure of the practical magnitude of a group difference or relationship. |
| Homoscedasticity | Var(ε|X) = σ² | Assumption that residual variance is constant across all levels of the predictor. |
Frequently Asked Questions
statsmodels automatically create dummy variables using formula syntax like C(variable). In scikit-learn, categorical variables can be encoded using OneHotEncoder or pandas.get_dummies() before fitting a regression model.
Real-World Applications
Clinical Trials
ANOVA compares mean outcomes across drug groups (treatment A vs B vs placebo). Regression models dose-response relationships and adjusts for baseline covariates.
Education Research
ANOVA tests whether teaching methods differ in student outcomes. Regression predicts exam scores from study hours, prior GPA, and class size simultaneously.
Manufacturing QC
ANOVA checks whether defect rates differ across machines or production shifts. Regression models how temperature and pressure affect product dimensions.
Marketing Analytics
ANOVA compares click-through rates across five ad formats. Regression predicts revenue from ad spend, season, and market size as continuous predictors.
Agriculture
ANOVA tests whether crop varieties differ in yield. Regression models how rainfall and fertilizer amount (continuous) predict yield, controlling for soil type.
Machine Learning
Regression is the foundation of many ML algorithms. ANOVA-style reasoning underlies model comparison (comparing error rates across models using F-tests).
ANOVA vs Regression Cheat Sheet
| Question | Use ANOVA When … | Use Regression When … |
|---|---|---|
| What is my IV type? | Categorical (group labels) | Continuous, or mixed |
| What is my DV type? | Continuous | Continuous (linear); binary (logistic) |
| How many groups? | 3 or more | N/A (predictors, not groups) |
| Primary goal? | Compare group means | Predict, estimate coefficients |
| Do I need a prediction equation? | No | Yes |
| Do I have covariates to control for? | Use ANCOVA instead | Add to the regression model |
| Test statistic | F(k−1, N−k) | F(p, N−p−1) overall; t per β |
| Effect size metric | η² (eta-squared) | R² and standardized β |
| Post-analysis needed? | Post-hoc tests (Tukey, Bonferroni) | Residual diagnostics, VIF check |
| Software function (R) | aov(y ~ group) | lm(y ~ x1 + x2) |
| Software function (Python) | stats.f_oneway(g1, g2, g3) | ols('y ~ x', data).fit() |
References and Further Reading
- Fisher, R.A. (1925) — Statistical Methods for Research Workers. Edinburgh: Oliver and Boyd. The foundational text for both ANOVA and the F-test.
- Cohen, J., Cohen, P., West, S.G., & Aiken, L.S. (2003) — Applied Multiple Regression/Correlation Analysis for the Behavioral Sciences (3rd ed.). Lawrence Erlbaum. Chapter 8 proves the equivalence of ANOVA and regression.
- NIST Engineering Statistics Handbook — One-Way ANOVA and Linear Regression. NIST/SEMATECH, freely accessible.
- Draper, N.R. & Smith, H. (1998) — Applied Regression Analysis (3rd ed.). Wiley-Interscience. Standard graduate textbook covering both OLS and ANOVA-as-regression.
- Penn State STAT 415 — Introduction to Mathematical Statistics. Free online course covering GLM theory.
- UCLA Statistical Consulting Group — What Statistical Analysis Should I Use? Comprehensive decision guide from UCLA's IDRE.
- R Documentation — aov() and lm() function documentation.