Celeus

How to report ANOVA results in APA style

APA 7 sentences for one-way, Welch's and two-way ANOVA with eta squared, partial eta squared and post hoc results, each filled from a real R run.

On this page

An APA-style ANOVA report gives the group means and standard deviations, F with its two degrees of freedom, the exact p-value, an effect size with its confidence interval, and then the post hoc comparisons that say which groups differ. This guide gives fill-in sentences for the one-way, Welch’s and two-way ANOVA, each filled from a real analysis run in R whose output you can check.

The examples also show two details most templates skip: which effect size label is correct for which design, and why a pairwise effect size can look “significant” while its adjusted comparison is not. For the general APA rules across all common tests, see the guide to reporting statistics in APA style.

What a complete ANOVA report contains

APA’s reporting standards for quantitative research (JARS-Quant, Appelbaum and colleagues, 2018) ask for the sample size of each group, the cell means and standard deviations, every inferential test with its exact p-value and degrees of freedom, and effect sizes with confidence intervals. For an ANOVA that becomes:

  1. The test, by name. One-way ANOVA, Welch’s ANOVA or two-way ANOVA. “An ANOVA” alone does not say whether variances were pooled or how many factors there were.
  2. Sample size per group, or per cell in a factorial design.
  3. Descriptive statistics: each group’s mean and standard deviation, in the text or a table.
  4. The omnibus test: F(df1, df2) = value, p = value.
  5. An effect size with its interval, labelled as eta squared (η²) or partial eta squared (η²p).
  6. Post hoc comparisons: the procedure named, each pairwise difference with its interval, and the adjusted p-values.

APA formatting rules for ANOVA statistics

APA’s numbers and statistics guide (the 7th-edition handout, last updated September 2024) sets how most numbers are typed; the eta squared and degrees-of-freedom points below follow from its logic or common practice rather than its text. The rules that matter most for ANOVA:

  • Italicize F, p, M, SD and n. Greek letters such as η are not italicized.
  • Degrees of freedom go in parentheses, between groups first: F(2, 27), never F(27, 2).
  • Two decimals for F, means and standard deviations, as a general rule.
  • Exact p-values to two or three decimals, and p < .001 for anything smaller. Never p = .000.
  • No leading zero for a statistic that cannot exceed 1. The guide names p-values, correlations and proportions; eta squared is a proportion of variance, so by the same rule write p = .016 and η² = .26. A mean difference or Hedges’ g can exceed 1, so they keep the zero: a difference of 0.87.
  • Define abbreviations other than the standard symbols, which includes CI and ANOVA, once before using them.
  • Keep the decimals of fractional degrees of freedom (not in the guide, but common practice). Welch’s ANOVA gives a second value such as 17.13; rounding it to 17 hides which test you ran.

Fill-in sentences for each ANOVA

Replace each bracketed slot with your own numbers. Descriptives come first, then the test, then the effect size, then the comparisons.

One-way ANOVA with Tukey’s HSD

Mean [outcome] differed across the [k] groups, F([df1], [df2]) = [F], p = [p], η² = [value], 95% CI [[LL], [UL]]. Tukey’s HSD comparisons showed that [group A] (M = [M], SD = [SD]) differed from [group B] (M = [M], SD = [SD]) by [difference], 95% CI [[LL], [UL]], adjusted p = [p], Hedges’ g = [g].

The classic one-way ANOVA pools the group variances, and Tukey’s HSD pools them the same way, which is why the two belong together.

Welch’s ANOVA with Games-Howell

Welch’s ANOVA showed that mean [outcome] differed across the [k] groups, F([df1], [df2, two decimals]) = [F], p = [p], η² = [value]. Games-Howell comparisons showed that [group A] differed from [group B], adjusted p = [p], Hedges’ g = [g], 95% CI [[LL], [UL]].

Welch’s test (Welch, 1951) does not assume equal variances, and Games-Howell (Games and Howell, 1976) estimates each group’s variance separately too. If you are still deciding between the classic, Welch and Kruskal-Wallis versions, the guide to one-way ANOVA, Welch and Kruskal-Wallis covers that choice.

Two-way ANOVA: interaction first

The interaction between [factor A] and [factor B] was [statistically significant / not statistically significant], F([df1], [df2]) = [F], p = [p], η²p = [value], 95% CI [[LL], [UL]]. [Describe the pattern with the cell means.] The main effect of [factor A] was F([df1], [df2]) = [F], p = [p], η²p = [value], and the main effect of [factor B] was F([df1], [df2]) = [F], p = [p], η²p = [value].

Report the interaction first, because it changes how the main effects should be read. Name the type of sums of squares in the methods, since with unequal cell sizes the types give different tests.

Worked example: one-way ANOVA on PlantGrowth

The example uses PlantGrowth, a dataset that ships with R and comes from Dobson’s 1983 textbook. It records the dried weight of 30 plants, 10 under each of three conditions: a control (ctrl) and two treatments (trt1 and trt2). Each plant belongs to one condition and is weighed once, so the three groups are independent, a one-way between-groups design. The classic one-way ANOVA was specified before the run. The output and the R script appear below the article, and the ANOVA in R walkthrough reads the aov() output for the same dataset line by line.

What the engine reported

Quantity Value
Plants analysed 30 (10 per condition)
F 4.846 on 2 and 27 degrees of freedom
p-value 0.0159
Eta squared 0.2641, 95% CI 0.01099 to 0.4902
Tukey: trt2 minus trt1 0.865, 95% CI 0.1738 to 1.556, adjusted p 0.01201, Hedges’ g 1.289 (0.3371 to 2.213)
Tukey: trt2 minus ctrl 0.494, 95% CI -0.1972 to 1.185, adjusted p 0.198, Hedges’ g 0.9139 (0.01252 to 1.793)
Tukey: trt1 minus ctrl -0.371, 95% CI -1.062 to 0.3202, adjusted p 0.3909, Hedges’ g -0.5102 (-1.359 to 0.3521)

From output to sentence

Rounded to APA’s conventions, with the leading zero dropped from p and η²:

Mean dried weight differed across the three conditions, F(2, 27) = 4.85, p = .016, η² = .26, 95% CI [.01, .49]. Tukey’s HSD comparisons showed that plants under the second treatment were heavier than plants under the first, a difference of 0.87, 95% CI [0.17, 1.56], adjusted p = .012, Hedges’ g = 1.29. Neither treatment differed clearly from the control: second treatment minus control 0.49, 95% CI [-0.20, 1.19], adjusted p = .198; first treatment minus control -0.37, 95% CI [-1.06, 0.32], adjusted p = .391.

The group means and standard deviations belong in front of that sentence or in a table. The engine run reports the differences, not the group descriptives, so they are left out here rather than typed by hand; aggregate(weight ~ group, data = PlantGrowth, FUN = function(x) c(M = mean(x), SD = sd(x))) prints them.

Two kinds of interval in the post hoc table

The Tukey intervals for the differences are simultaneous: all three are adjusted together, so they agree with the adjusted p-values. The interval for second treatment minus control, [-0.20, 1.19], includes zero, matching its adjusted p of .198.

The Hedges’ g interval for the same pair is 0.01 to 1.79, which excludes zero. Nothing is wrong: each g interval is computed for its pair alone, with no adjustment for the three comparisons. If you report pairwise effect sizes, say that their intervals are unadjusted, and base the claim about which groups differ on the adjusted results. Otherwise a reader can find a “significant” effect size the comparison itself does not support.

The compact letter display summarises the same result: ctrl (ab), trt1 (a), trt2 (b). Groups sharing a letter are not significantly different at the adjusted .05 threshold, so only trt1 and trt2 separate.

Eta squared, not partial eta squared, here

With one factor, eta squared and partial eta squared are the same number, because the only sources of variation are the factor and the error. Label it η², and note that with 10 plants per group its interval, .01 to .49, is wide. The eta squared guide explains why the two measures separate as soon as there is a second factor, and Lakens’ 2013 primer sets out how to compute and report each.

The same data with Welch’s ANOVA

Welch’s ANOVA and Games-Howell comparisons on these same 30 plants are worked through in full, with a filled report sentence, in the ANOVA test explained post. Three points matter when you write that version up:

  • Keep the decimals of the second degrees of freedom, as in F(2, 17.13) for these data.
  • Say how the effect size was computed. The η² is still the classical ratio of the between-groups to the total sum of squares, the same .26 as above, because Welch’s adjustment changes F and its degrees of freedom, not that ratio. If you quote its interval, say that it comes from the pooled-variance F rather than Welch’s.
  • State each comparison’s direction in words. In the run behind that post, Games-Howell gives adjusted p-values without intervals for the differences, so the pairwise g with its unadjusted interval carries the size there, and its sign depends on which group the software subtracts.

Choose the version before the run, not by comparing their results. The post hoc tests guide explains why each omnibus test has its own follow-up.

Two-way ANOVA: a companion run on ToothGrowth

PlantGrowth has only one factor, so the two-way example uses ToothGrowth, another R dataset: the length of odontoblasts (the cells responsible for tooth growth) in 60 guinea pigs from Crampton’s 1947 experiment, crossing delivery method (orange juice or ascorbic acid) with three doses (0.5, 1 and 2 mg a day). Each of the six cells has 10 animals, each measured once, a balanced between-subjects design. The engine tested each term from a Type II table. The same three F statistics are the worked example in how to find a p-value from a test statistic, which recomputes their p-values by hand; here the point is the write-up, so each term gets its partial eta squared and interval, and the interaction comes first:

The effect of delivery method depended on dose, F(2, 54) = 4.11, p = .022, η²p = .13, 95% CI [.001, .295]. Mean odontoblast length was higher with orange juice than with ascorbic acid at 0.5 mg (13.23, 95% CI [10.93, 15.53], vs 7.98 [5.68, 10.28]) and at 1 mg (22.70 [20.40, 25.00] vs 16.77 [14.47, 19.07]), but not at 2 mg (26.06 [23.76, 28.36] vs 26.14 [23.84, 28.44]). Averaged over doses, delivery method had a main effect, F(1, 54) = 15.57, p < .001, η²p = .22, 95% CI [.06, .40], and dose had a main effect, F(2, 54) = 92.00, p < .001, η²p = .77, 95% CI [.66, .84].

The interaction’s interval is shown to three decimals because two would print its lower limit as .00, which reads as zero. The cell-mean pattern is a description; a formal claim that the methods differ at one dose but not another needs simple-effects tests, which this run does not include. The main effect of delivery method is an average over doses, and at the highest dose the two methods gave nearly the same mean (26.06 and 26.14), which is exactly why the interaction comes first. The two-way ANOVA guide covers simple effects and sums-of-squares types.

What goes in the methods section

The results sentences need a methods paragraph that lets a reader judge the test (the statistical analysis paragraph shows a full one):

  • The test and why: “Mean dried weight was compared across the three conditions with a one-way ANOVA, followed by Tukey’s HSD.”
  • How independence follows from the design: each plant was weighed once and belongs to one condition.
  • What you checked, in neutral words. In the example, Shapiro-Wilk tests found no evidence against normality in any group (ctrl p = .747, trt1 p = .452, trt2 p = .564), and Levene’s test found no evidence of unequal variances (p = .341). “No evidence of” is not proof of equality; with 10 plants per group these checks have little power.
  • A sensitivity statement for small designs. The engine flagged the study as small: with 10 per group, a test at the .05 level had 80% power only for effects of Cohen’s f = 0.60 or larger, and detecting f = 0.25 would need 53 per group. Label this a sensitivity analysis of the design, never “observed power” computed from the result.
  • The software, its version and where the script is.

Common reporting mistakes

Calling every effect size “eta squared”. In a factorial design, a value computed as partial eta squared and labelled η² overstates what share of the total variation the term explains. Label it η²p.

Reporting the omnibus test and stopping. A significant F says the means are not all equal, not which groups differ or by how much.

Reading a non-significant comparison as “no difference”. Second treatment minus control had an interval of -0.20 to 1.19: compatible with no difference and with a sizeable one. Greenland and colleagues (2016) list “no difference” readings of non-significant results among the common misinterpretations of tests and intervals.

Mixing adjusted and unadjusted results without saying which is which. Name the adjustment for the comparisons, and say when an interval, such as the pairwise g intervals here, is unadjusted. The multiple comparisons guide explains the options.

Rerunning the example

The R script below the article is the one the engine generated for the one-way run, followed by the engine’s summary of its results. On the same package versions it recomputes the F test, eta squared with its interval, the Tukey comparisons and the sensitivity figure. The Hedges’ g values and the assumption checks are not in it; effectsize::hedges_g() on each pair, shapiro.test() within each group and car::leveneTest(weight ~ group, data = data) reproduce them. The Welch figures and the two-way sentences come from two companion runs with their own scripts, not shown on this page.

The methods are documented on the engine’s reference pages for the one-way ANOVA, Welch’s ANOVA and the two-way ANOVA. For the same reporting conventions applied to two groups, see how to report a t-test, and the guide to reproducible statistical analysis explains what a reviewer needs to rerun a result like this one.

Reproduce this

Worked example

Data: Dobson AJ (1983). An Introduction to Statistical Modelling. London: Chapman and Hall. doi:10.1007/978-1-4899-3174-0. Seed: 20261101.

Run on Celeus engine 0.41.7, seed 20261101, public data.

Output

# Results

- Test: One-way ANOVA
- n: 30
- statistic: 4.846
- p-value: 0.0159
- effect size: eta-squared = 0.2641 (95% CI 0.01099 to 0.4902)
  (two-sided CI at the run's confidence level)
- seed: 20261101

## Assumption checks
- normality by group (Shapiro-Wilk): passed=TRUE
- variance homogeneity (Levene): passed=TRUE (no evidence of unequal variances)

## Post-hoc (Tukey HSD; correction: single-step (Tukey))
- trt1 vs ctrl: adj p = 0.3909 | diff -0.371 [-1.062, 0.3202] | Hedges' g -0.5102 [-1.359, 0.3521]
- trt2 vs ctrl: adj p = 0.198 | diff 0.494 [-0.1972, 1.185] | Hedges' g 0.9139 [0.01252, 1.793]
- trt2 vs trt1: adj p = 0.01201 | diff 0.865 [0.1738, 1.556] | Hedges' g 1.289 [0.3371, 2.213]

groups: ctrl (ab), trt1 (a), trt2 (b) - groups sharing a letter are not significantly different at the adjusted threshold.

## Power (sensitivity, not observed power)
- minimum detectable effect at n=30: Cohen's f = 0.5997 (severely underpowered)
- to detect a conventional medium effect: 53 per group to detect f=0.25
- alpha = 0.05, target power = 0.8
R script
# Celeus - reproduce.R  (run from this package folder; bundled data in data/)
# Test: One-way ANOVA  |  engine 0.41.7  |  catalog c40-dc08
# Research context: not provided for this run.
# Reproduces the recorded result deterministically.

set.seed(20261101)
.data_path <- "data/how-to-report-anova.csv"
if (!file.exists(.data_path)) stop("Run reproduce.R from the package folder (the bundled data is in data/).")
data <- readr::read_csv(.data_path, show_col_types = FALSE)  # needs the readr package
clean_cells <- function (df) 
{
    ctrl_collapse <- "[\r\n\t\v\f]+"
    zero_width_chars <- intToUtf8(c(8203L, 65279L), multiple = TRUE)
    uni_space_chars <- intToUtf8(c(160L, 8239L, 8199L), multiple = TRUE)
    clean_text <- function(x) {
        out <- x
        for (ch in zero_width_chars) out <- gsub(ch, "", out, 
            fixed = TRUE)
        out <- gsub(ctrl_collapse, " ", out)
        for (ch in uni_space_chars) out <- gsub(ch, " ", out, 
            fixed = TRUE)
        trimws(gsub(" +", " ", out))
    }
    changed_cols <- character(0)
    cells_cleaned <- 0L
    retyped <- character(0)
    for (j in seq_along(df)) {
        col <- df[[j]]
        if (!is.character(col)) 
            next
        cleaned <- clean_text(col)
        n_changed <- sum(!is.na(col) & !is.na(cleaned) & col != 
            cleaned, na.rm = TRUE)
        if (n_changed > 0L) {
            changed_cols <- c(changed_cols, names(df)[j])
            cells_cleaned <- cells_cleaned + n_changed
        }
        df[[j]] <- cleaned
        non_blank <- cleaned[!is.na(cleaned) & nzchar(cleaned)]
        if (length(non_blank) && all(grepl("^[+-]?(0|[1-9][0-9]*)([.][0-9]+)?$", 
            non_blank))) {
            parsed <- suppressWarnings(as.numeric(cleaned))
            was_blank <- is.na(cleaned) | !nzchar(cleaned)
            lost <- (is.na(parsed) | is.infinite(parsed)) & !was_blank
            if (!any(lost)) {
                finite <- parsed[!is.na(parsed)]
                all_whole <- all(finite == floor(finite))
                in_range <- all(abs(finite) <= .Machine$integer.max)
                df[[j]] <- if (all_whole && in_range) 
                  as.integer(parsed)
                else parsed
                retyped <- c(retyped, names(df)[j])
            }
        }
    }
    names(df) <- clean_text(names(df))
    if (length(changed_cols)) {
        attr(df, "ingest_clean_columns") <- changed_cols
        attr(df, "ingest_clean_cells_cleaned") <- cells_cleaned
    }
    if (length(retyped)) 
        attr(df, "ingest_clean_retyped") <- retyped
    df
}
data <- clean_cells(data)
# Complete-case analysis: drop rows missing any analysis value.
.acols <- c("weight", "group")
data <- data[stats::complete.cases(data[, .acols, drop = FALSE]), , drop = FALSE]
result <- oneway.test(`weight` ~ `group`, data = data, var.equal = TRUE)
print(result)

# Effect size (Eta2) and its confidence interval.
effect <- { .es_d <- data; .es_d[["group"]] <- as.factor(.es_d[["group"]]); .es_d[["weight"]] <- .es_d[["weight"]] - stats::median(.es_d[["weight"]], na.rm = TRUE); effectsize::eta_squared(stats::aov(`weight` ~ `group`, data = .es_d), partial = FALSE, ci = 0.95, alternative = "two.sided") }
print(effect)

# Post-hoc pairwise comparisons (Tukey HSD; correction: single-step (Tukey)).
data[["group"]] <- as.factor(data[["group"]])
posthoc <- { .ph_d <- data.frame(.y = data[["weight"]], .g = as.factor(data[["group"]])); .ph_tk <- stats::TukeyHSD(stats::aov(.y ~ .g, data = .ph_d)); names(.ph_tk) <- "group"; .ph_tk }
print(posthoc)

# Sensitivity: minimum detectable effect at n=30 (power=0.8, alpha=0.05). NOT observed power.
power <- pwr::pwr.anova.test(k = 3, n = 10, sig.level = 0.05, power = 0.8)
print(power)

Download the files

Common questions

How do I report a one-way ANOVA in APA style?

Name the test, give each group's mean and standard deviation, then F with its two degrees of freedom in parentheses (between groups first), the exact p-value without a leading zero, and eta squared with its 95% confidence interval. Follow with the named post hoc procedure and each pairwise difference with its interval and adjusted p-value.

Should I report eta squared or partial eta squared for ANOVA?

In a one-way ANOVA the two are the same number, so either label is correct; say which one you mean. With two or more factors they differ, because partial eta squared leaves the other factors out of the denominator. Label it as partial, and never compare it with a classical eta squared from another study.

How do I report Welch's ANOVA in APA style?

Write it like the classic F, but name the test and keep the decimals in the second degrees of freedom, for example F(2, 17.13). Those fractional degrees of freedom show the reader that the group variances were not pooled. Follow it with Games-Howell comparisons, which also do not pool the variances.

How do I report a two-way ANOVA with a significant interaction?

Report the interaction first, with its F, degrees of freedom, p-value and partial eta squared with its interval. Then describe the pattern with the cell means and their intervals, because a main effect averaged over the other factor can describe no condition that actually occurred. Report the main effects after that, in the same format.

Do I report post hoc tests if the ANOVA is not significant?

Tukey's HSD (under its equal-variance assumption) and Games-Howell (approximately, unless the groups are very small) control the family-wise error rate on their own, so a significant F is not strictly required before them; requiring one is a common convention, but it makes the combined procedure more conservative. Decide your rule before seeing the data, state it in the methods, and report every comparison you ran.

Sources

  1. American Psychological Association (2024). APA Style numbers and statistics guide (7th ed. handout, last updated September 11, 2024). apastyle.apa.org
  2. Appelbaum M, Cooper H, Kline RB, Mayo-Wilson E, Nezu AM, Rao SM (2018). Journal article reporting standards for quantitative research in psychology: the APA Publications and Communications Board task force report. American Psychologist 73(1):3-25. doi:10.1037/amp0000191
  3. Lakens D (2013). Calculating and reporting effect sizes to facilitate cumulative science: a practical primer for t-tests and ANOVAs. Frontiers in Psychology 4:863. doi:10.3389/fpsyg.2013.00863
  4. Welch BL (1951). On the comparison of several mean values: an alternative approach. Biometrika 38(3-4):330-336. doi:10.1093/biomet/38.3-4.330
  5. Games PA, Howell JF (1976). Pairwise multiple comparison procedures with unequal N's and/or variances: a Monte Carlo study. Journal of Educational Statistics 1(2):113-125. doi:10.3102/10769986001002113
  6. Crampton EW (1947). The growth of the odontoblasts of the incisor tooth as a criterion of the vitamin C intake of the guinea pig. Journal of Nutrition 33(5):491-504. doi:10.1093/jn/33.5.491
  7. Greenland S, Senn SJ, Rothman KJ, Carlin JB, Poole C, Goodman SN, Altman DG (2016). Statistical tests, P values, confidence intervals, and power: a guide to misinterpretations. European Journal of Epidemiology 31(4):337-350. doi:10.1007/s10654-016-0149-3

Methods discussed

Try it on your own data

Upload a dataset and Celeus suggests a method, checks its assumptions, runs it in R, and gives you the script to rerun it.

Try it in Celeus