Written and maintained by CASRAI Editorial Board
Last updated
anova is Stata’s command for fitting analysis-of-variance models — one-way, factorial, and repeated-measures — and reporting the result as a classic ANOVA table (Source, SS, df, MS, F, Prob > F) rather than a regression coefficient table. This page covers anova syntax for one-way and factorial designs, how to read the table it prints, the repeated() option for within-subject designs, and the postestimation workflow — margins for group means and pwcompare for post hoc pairwise comparisons — that anova itself does not print automatically.
For the statistical logic behind ANOVA itself — what the F-ratio tests, what the assumptions are, and how to interpret it regardless of software — see CASRAI’s ANOVA dictionary entry. If you work in R or SPSS instead, see running ANOVA in R or one-way ANOVA in SPSS. This page is the Stata-specific procedure.
anova vs. oneway: choosing the right command
Stata has two commands for ANOVA, and picking the wrong one for the job is the most common early mistake:
onewayis a dedicated, simpler command for a single-factor (one-way) design only:oneway depvar groupvar. It prints the ANOVA table plus, in the same run, Bartlett’s test for equal variances and built-in post hoc options —oneway score group, bonferroni schefferuns Bonferroni- and Scheffe-adjusted pairwise comparisons directly, no separate postestimation step required.anovais the general command: one-way, factorial (multiple categorical factors and their interactions), ANCOVA with a continuous covariate, and repeated-measures designs. It does not print post hoc comparisons on its own — that’s whatmarginsandpwcompareare for, covered below.
If your design really is a single factor and you just need a quick omnibus test with a standard post hoc correction, oneway is the faster path. As soon as you have a second factor, an interaction, a covariate, or a within-subject repeated factor, you need anova.
One-way ANOVA syntax with anova
Basic syntax lists the dependent variable followed by one or more model terms:
anova depvar termlist
A one-way design — a satisfaction score compared across three training-program formats:
anova score program
Unlike regress, anova treats every variable in the termlist as categorical by default — there is no need for the i. factor-variable prefix that regress requires for categorical predictors. If a variable in your model is genuinely continuous (a covariate, not a grouping factor), you mark it explicitly with the c. prefix instead.
Reading the ANOVA table
Here is what anova prints (illustrative numbers, laid out to show the format — not a reported research finding):
Number of obs = 90 R-squared = 0.0837 Root MSE = 4.61466 Adj R-squared = 0.0625 Source | Partial SS df MS F Prob>F ------------+---------------------------------------------------- Model | 169.155556 2 84.5777778 3.97 0.0225 | program | 169.155556 2 84.5777778 3.97 0.0225 | Residual | 1852.66667 87 21.2949042 ------------+---------------------------------------------------- Total | 2021.82222 89 22.7171036
The row named after your factor (program here) is the term you care about — its Prob>F is the omnibus significance test for that factor. In a one-way design the Model row and the factor’s own row are identical, since the factor is the only term in the model. In a factorial design (next section) each term — each main effect and each interaction — gets its own row with its own F-test, and the Model row becomes their combined total.
Factorial designs: main effects and interactions
List additional categorical factors as additional terms. An interaction between two factors uses #:
anova score program site program#site
## is shorthand for “this factor and everything it interacts with” — program##site expands to exactly program site program#site, so the two lines above are equivalent. This gives you the full factorial: both main effects plus their interaction, each reported as a separate row in the table with its own F-test.
To add a continuous covariate (ANCOVA) rather than a second categorical factor, prefix it with c.:
anova score c.pretest_score program
Repeated-measures ANOVA with repeated()
A within-subject (repeated) factor — the same subjects measured at multiple time points or conditions — needs two things: a / in the model specification to mark where the between-subjects error term ends, and the repeated() option naming which factor is the repeated one:
anova score group / subject|group time group#time, repeated(time)
Reading this left to right: group is the between-subjects factor, tested against the subject|group error term (subjects nested within group) rather than the residual; after the /, time and group#time are the within-subject terms. repeated(time) tells Stata that time is measured within the same subjects, which is what triggers the sphericity-sensitive corrected significance levels in the output for the within-subject terms — the same Greenhouse-Geisser/Huynh-Feldt logic that applies to repeated-measures ANOVA in any package, not a Stata-specific statistical rule.
Postestimation: margins for group means
anova reports whether a factor’s effect is significant, not what the group means actually are. margins, run immediately after anova, computes those:
margins program
This reports the adjusted (marginal) mean of the outcome at each level of program, holding any other model terms at their observed values — the number to report alongside the ANOVA table’s F-test, and the input to a means plot via marginsplot. In a factorial model, margins program#site gives the mean at every combination of the two factors, which is what you need to interpret a significant interaction term.
Postestimation: pwcompare for post hoc comparisons
A significant omnibus F-test tells you the group means aren’t all equal; it doesn’t say which pairs differ. pwcompare, run after anova, tests every pair of levels of a factor with a chosen multiple-comparison correction:
pwcompare program, mcompare(bonferroni) effects
mcompare() accepts the standard corrections — bonferroni, sidak, scheffe, tukey, among others — and the effects option adds the estimated difference, its confidence interval, and p-value for each pair to the default group-comparison table. Which correction to choose is a design question (Tukey for all-pairwise comparisons of equal-variance groups, Scheffe when you also want to test arbitrary contrasts, Bonferroni as the simplest and most conservative default) rather than a Stata-specific one — the same trade-off you’d weigh choosing a post hoc test in any package.
contrast for planned comparisons
If you have specific, planned comparisons rather than every possible pair — for example, each treatment level against a single control level — contrast is the more targeted tool:
contrast g.program
Reference-style contrast operators (r. for comparisons against a reference/base level, g. for pairwise grand-mean-style comparisons, among others) let you test exactly the comparisons your design calls for instead of every pair pwcompare would test, which keeps the multiple-comparison correction from being spread more thinly than the actual number of questions you’re asking.
Frequently asked questions
Do I need to write i.program in the anova command?
No. Unlike regress, anova treats variables in the termlist as categorical by default — no i. prefix needed. Use the c. prefix only to mark a variable as a continuous covariate instead.
Can I run post hoc tests directly from oneway instead of anova plus pwcompare?
Yes, for a genuine one-way design: oneway score group, bonferroni scheffe runs the adjusted pairwise comparisons in the same command. That shortcut only exists for the single-factor case — a factorial or repeated-measures design needs anova followed by pwcompare or contrast.
What is the difference between pwcompare and contrast?
pwcompare tests every pairwise comparison among a factor’s levels with a multiple-comparison correction. contrast tests specific, named comparisons you choose — against a reference level, for example — which is the better fit when you have planned comparisons rather than an all-pairs question.
Why does anova give a different-looking table than regress for the same model?
They can fit the same underlying linear model — anova is built on the same OLS estimation as regress — but anova summarizes it by model term (one F-test per factor or interaction) while regress summarizes it by individual coefficient. Use anova when the question is “does this factor matter,” and regress when the question is “what is the effect of this specific predictor.”








