Model library Analysis of Covariance (ANCOVA)
Statistical model reference

Analysis of Covariance (ANCOVA)

Review when to use this method, its data requirements, implementation patterns, and interpretation guidance.

Description

A statistical technique that combines ANOVA and regression to compare group means while controlling for the effects of continuous covariates. It adjusts for confounding variables and increases statistical power by accounting for variance explained by covariates.

Use Cases
  • adjusted group comparisons
  • covariate control in experiments
  • baseline adjustment
Requirements
  • Sample Size: medium, large
  • Missing Data: none, random
  • Data Distribution: normal
  • Relationship Type: linear
Variable Types
Dependent Variables
  • continuous
Independent Variables
  • categorical
  • continuous
Implementation
import statsmodels.api as sm
from statsmodels.formula.api import ols

model = ols('dependent_var ~ C(group_var) + covariate', data=df).fit()
ancova_table = sm.stats.anova_lm(model, typ=2)
print(ancova_table)
Documentation
model <- aov(dependent_var ~ group_var + covariate, data=df)
summary(model)
emmeans::emmeans(model, pairwise ~ group_var, adjust="tukey")
Documentation
GLM dependent_var BY group_var WITH covariate
  /METHOD=SSTYPE(3)
  /INTERCEPT=INCLUDE
  /POSTHOC=group_var(TUKEY)
  /PRINT=DESCRIPTIVE PARAMETER
Documentation
PROC GLM DATA=dataset;
  CLASS group_var;
  MODEL dependent_var = group_var covariate / SOLUTION;
  LSMEANS group_var / PDIFF ADJUST=TUKEY;
RUN;
Documentation
anova dependent_var group_var covariate
margins group_var, post
contrast r.group_var, effects
Documentation
Synthetic Data Example

A dataset with one continuous dependent variable, one categorical independent variable, and one continuous covariate

R Code for Data Generation and Analysis
# Generate synthetic ANCOVA data
set.seed(123)

# Create covariate
covar <- rnorm(90, mean=50, sd=10)

# Create groups with different intercepts and slopes
df <- data.frame(
  value = c(30 + 0.7*covar[1:30] + rnorm(30, sd=3),
            40 + 0.5*covar[31:60] + rnorm(30, sd=3),
            50 + 0.3*covar[61:90] + rnorm(30, sd=3)),
  group = factor(rep(c("A", "B", "C"), each=30)),
  covariate = covar
)

# Visualization
library(ggplot2)
ggplot(df, aes(x=covariate, y=value, color=group)) +
  geom_point() +
  geom_smooth(method="lm") +
  ggtitle("ANCOVA Data with Group-Specific Regression Lines")

# ANCOVA model
model <- aov(value ~ group + covariate, data=df)
summary(model)

# Adjusted means
library(emmeans)
emmeans(model, pairwise ~ group, adjust="tukey")

# Assumption checking
plot(model, which=1:2)
car::leveneTest(residuals(model) ~ group, data=df)
Copy this code into your R environment to generate synthetic data and perform analysis with this model.
Expected Analysis Results
Console Output

> summary(model)
            Df Sum Sq Mean Sq F value   Pr(>F)
group        2  2456.7  1228.4  145.67  < 2e-16 ***
covariate    1   876.5   876.5  103.95  < 2e-16 ***
Residuals   86   725.3     8.4                     
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

> emmeans(model, pairwise ~ group, adjust="tukey")
$emmeans
 group emmean    SE df lower.CL upper.CL
 A       45.2 0.53 86     44.1     46.2
 B       55.3 0.53 86     54.2     56.3
 C       65.1 0.53 86     64.0     66.1

$contrasts
 contrast estimate    SE df t.ratio p.value
 A - B      -10.12 0.75 86 -13.489  <.0001
 A - C      -19.92 0.75 86 -26.549  <.0001
 B - C       -9.80 0.75 86 -13.060  <.0001
These results are from running the R code on synthetic data. Your actual results may vary depending on your data.
Interpretation Guide

Need help interpreting the results of your Analysis of Covariance (ANCOVA) analysis? Our comprehensive interpretation guide explains:

  • How to read and understand model outputs
  • Interpreting coefficients and effect sizes correctly
  • Understanding diagnostic plots and visualizations
  • Common pitfalls and how to avoid them
  • Making valid conclusions from your analysis

Statistical assistant