Math & Scientific
Calculate One-Way ANOVA from Grouped Observations
Build a one-way ANOVA table from three groups, check sums of squares and degrees of freedom, and interpret F without losing group labels.
Specify the comparison and preserve group membership
A classical one-way ANOVA compares population means for one categorical factor with two or more levels. Its null hypothesis says all group means are equal; the alternative says at least one differs. Record each observation with its group before calculating. Pasting all values into an ordinary variance form discards the division into groups and cannot perform this test. Repeated measurements on the same unit, multiple factors or unequal-variance procedures require a method appropriate to that design.
Calculate three group means and the grand mean
Use group A: 2, 4, 6; group B: 8, 10, 12; and group C: 14, 16, 18. Their means are 4, 10 and 16, and each group has three observations. The nine-value grand mean is 10. When group sizes differ, calculate the grand mean from all observations or from a size-weighted mean of group means. An unweighted average of group means is correct here because the sizes happen to be equal, not because it is the general rule.
Partition the total sum of squares
The between-group sum of squares is 3(4−10)²+3(10−10)²+3(16−10)²=216. Within each group, deviations from its own mean are −2, 0 and 2, contributing eight squared units per group. The within-group sum of squares is therefore 24. The total around the grand mean is 216+24=240. Keeping between, within and total labels explicit avoids confusing the variation explained by group differences with the residual variation remaining inside groups.
Build the degrees of freedom and mean squares
There are k=3 groups and N=9 observations. Between-group degrees of freedom are k−1=2; within-group degrees of freedom are N−k=6; total degrees of freedom are N−1=8. Dividing sums of squares by their respective degrees of freedom gives between-group mean square 216/2=108 and within-group mean square 24/6=4. The F statistic is their ratio, 108/4=27. Do not divide both sums of squares by the same observation count, which would remove the required degrees-of-freedom adjustment.
Interpret the F-test under its assumptions
For F=27 with numerator degrees of freedom two and denominator degrees of freedom six, the upper-tail p-value is 0.001. Under the classical model, this is evidence against equal population means at a prespecified five-percent level. It does not identify every differing pair or measure the practical importance of differences. Pairwise follow-up comparisons need a suitable multiplicity adjustment or a planned contrast. Independence, approximately normal model errors and a common within-group variance are substantive assumptions, not properties established merely by obtaining an F statistic.
Use ordinary variance only as an arithmetic check
Entering the flattened first list in the local variance form gives sample variance 30. Multiplying by N−1=8 recovers total sum of squares 240. For a second example, take A: 2, 3, 4; B: 3, 4, 5; C: 4, 5, 6. The grand mean is four, between sum of squares six and within sum of squares six. Its F statistic is three and upper-tail p-value 0.125. The pooled sample variance is 1.5, which times eight recovers total 12.
Reproduce the table without a specialist package
The Python code below retains the groups, computes means, partitions sums of squares and verifies the decomposition. For these particular three groups of three observations, the F distribution has degrees of freedom two and six, and its upper-tail probability simplifies to (1+F/3)⁻³. That shortcut is not a general p-value formula for arbitrary group counts or sample sizes. A statistical library or an F-distribution table should use the actual degrees of freedom for a different design.
from statistics import mean
def table(groups):
k = len(groups)
values = [x for group in groups for x in group]
n, grand = len(values), mean(values)
between = sum(len(g) * (mean(g) - grand)**2 for g in groups)
within = sum((x - mean(g))**2 for g in groups for x in g)
total = sum((x - grand)**2 for x in values)
assert abs(total - between - within) < 1e-10
f = (between / (k - 1)) / (within / (n - k))
return between, within, total, f
groups = [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
print(table(groups)) # (216, 24, 240, 27.0)
print((1 + table(groups)[3] / 3)**-3) # 0.001
Report the analysis rather than just a decision
For the first data set, report the three sample sizes and means, F(2,6)=27 and p=0.001, along with the design and assumptions. A small p-value does not prove causation when the groups came from an observational process. A large p-value, as in the second example, does not prove identical means or sufficient study power. Inspect residuals and the collection process, and choose a different model when dependence or variance differences make the classical pooled-error analysis unsuitable.
Calculator for the supported step
The local Variance Calculator checks a raw list’s ordinary variance. It does not perform ANOVA, accept group labels or calculate an F-test p-value. The worked ANOVA below is calculated separately; a pooled-list variance supplies only a check on total sum of squares.