Chi-square test and Fisher's exact test
What the chi-square statistic actually compares, where the expected-count-of-five rule came from, what Fisher's exact test solves and what it costs, why Yates's correction is contested, and why paired categorical data must switch to McNemar.
What this method solves
Both variables are categorical (smoker or not, low birth weight or not) and the data collapse into a contingency table. The question is: is the pattern in this table far enough from what “the two variables are unrelated” would produce?
The chi-square test turns that into arithmetic. First compute how many people each cell should hold if the two variables were independent, by multiplying the margins back out:
Then add up the departures cell by cell:
That in the denominator is what makes the statistic work: being five people out is nothing in a cell that expected 100, and a great deal in a cell that expected 6. Under the null hypothesis this statistic approximately follows a chi-square distribution with degrees of freedom — note the word approximately, because every argument later on this page grows out of it.
The example here is MASS::birthwt: 189 mothers, asking whether maternal smoking and low birth weight (< 2500 g) are associated.
Running it yourself
library(MASS)
data(birthwt, package = "MASS")
birthwt$smoke_f <- factor(birthwt$smoke, levels = c(0, 1),
labels = c("Non-smoker", "Smoker"))
birthwt$low_f <- factor(birthwt$low, levels = c(0, 1),
labels = c(">= 2500 g", "< 2500 g"))
tb <- table(birthwt$smoke_f, birthwt$low_f)
tb
cs <- chisq.test(tb) # 2x2 carries Yates's correction by default
cs
cs$expected # <- look at this before choosing a test
chisq.test(tb, correct = FALSE)
fisher.test(tb) # exact test; also returns the OR and its CI
# Effect size: the chi-square statistic is not one.
# phi comes from the UNcorrected statistic, so do not reuse cs here.
sqrt(chisq.test(tb, correct = FALSE)$statistic / sum(tb)) # phi (Cramér's V for a 2x2)
# Paired categorical data needs a different method (same people, twice)
approval <- matrix(c(794, 86, 150, 570), nrow = 2)
mcnemar.test(approval)Verified with R 4.6.0 and MASS 7.3.65. chisq.test() applies correct = TRUE (Yates's correction) to a 2x2 table by default, which is the subject of the section on Yates's correction below.
import statsmodels.api as sm
import numpy as np
from scipy import stats
from statsmodels.stats.contingency_tables import mcnemar, Table2x2
bw = sm.datasets.get_rdataset("birthwt", "MASS").data
tb = np.array([[sum((bw.smoke == 0) & (bw.low == 0)), sum((bw.smoke == 0) & (bw.low == 1))],
[sum((bw.smoke == 1) & (bw.low == 0)), sum((bw.smoke == 1) & (bw.low == 1))]])
chi2, p, dof, expected = stats.chi2_contingency(tb) # correction=True by default
print(expected) # <- expected counts first
stats.fisher_exact(tb)
t2 = Table2x2(tb)
print(t2.oddsratio, t2.oddsratio_confint())
mcnemar(np.array([[794, 150], [86, 570]]), exact=False, correction=True)scipy's chi2_contingency likewise defaults to correction=True, and it too only applies to 2x2 tables.
How to read this table
| >= 2500 g (observed / expected) | < 2500 g (observed / expected) | Total | |
|---|---|---|---|
| Non-smoker | 86 / 79.1 | 29 / 35.9 | 115 |
| Smoker | 44 / 50.9 | 30 / 23.1 | 74 |
figures/scripts/B1-03-chi-square.RAmong smokers 30/74 = 40.5% of infants were of low birth weight, against 29/115 = 25.2% among non-smokers.
| Quantity | Result |
|---|---|
| Pearson chi-square (uncorrected) | = 4.92, df = 1, p = 0.026 |
| With Yates’s correction | = 4.24, df = 1, p = 0.040 |
| Fisher’s exact test | p = 0.036 |
| Smallest expected count | 23.1 |
| Odds ratio | 2.02 (95% CI 1.08–3.78) |
| Risk ratio | 1.61 (95% CI 1.06–2.44) |
| Absolute risk difference | 15.3 percentage points |
| (Cramér’s V for a 2×2) | 0.161 |
Three effect measures, each with its own home:
- Risk ratio (RR): for cohort studies and trials. It is simply the ratio of two risks, and it is the easiest to interpret.
- Odds ratio (OR): a case-control study can only produce an OR, because the design fixes the number of cases and controls and no risk can be computed; logistic regression coefficients are ORs as well. The OR approximates the RR for rare outcomes, but for an outcome as common as the 25% here it clearly overstates it (2.02 against 1.61).
- Cramér’s V: for tables, ranging from 0 to 1, with no direction. Useful for describing strength of association, hard to interpret clinically.
The expected-count-of-five line
The rule is usually remembered as “you cannot use a chi-square test if any expected count is below 5”. The original is more permissive: what Cochran recommended in the 1950s was that all expected counts be at least 1, and that no more than 20% of cells have an expected count below 5. For a 2×2 table, 20% is less than one cell, which is how the rule collapsed into “no cell below 5”.
Three things to keep hold of:
- It is a rule of thumb, not a theorem. There is no derivation behind the number 5; it comes from numerical checks on the quality of the chi-square approximation made in the 1950s.
- It governs the approximation, not the data. When expected counts are small, the distribution of the statistic is discrete and lumpy, and a continuous chi-square distribution approximates it badly. That has nothing to do with whether the data themselves are any good.
- It is about expected counts, not observed ones. A cell with zero observations is not automatically a violation, while a cell with an expected count of 4.2 violates the rule however many people happen to land in it. Which is why the first thing to do after
chisq.test()is to print$expected.
The same dataset supplies a ready-made example. Restrict the analysis to the race == Black stratum (n = 26):
| >= 2500 g (observed / expected) | < 2500 g (observed / expected) | |
|---|---|---|
| Non-smoker | 11 / 9.2 | 5 / 6.8 |
| Smoker | 4 / 5.8 | 6 / 4.2 |
The smallest expected count falls to 4.2, breaking the rule. The three calculations give: uncorrected Pearson 0.149, Fisher’s exact 0.228, Yates-corrected 0.300 — on this table Yates’s correction is the most conservative of the three and the uncorrected Pearson the least. Note that Fisher is not guaranteed to be more conservative than Yates in every dataset; what the simulation in the next two sections shows is that both sit below the nominal level on average, not that one always follows the other. The confidence interval for the OR runs from 0.63 to 17.16. None of the three calculations reaches statistical significance here, but what actually needs saying is that this stratum has nowhere near enough patients to detect an association of even moderate size — the width of that confidence interval says so, and a p-value cannot.
When to use Fisher’s exact test
Fisher’s exact test makes no approximation. It holds both sets of margins fixed, enumerates every table those margins allow, and uses the hypergeometric distribution to compute the probability of a result at least this extreme. Because it never leans on a large-sample approximation, it remains valid however small the expected counts are.
Reach for it when:
- any expected count is below 5 (or the table total is simply small);
- the table contains a zero;
- the sample is small enough that the approximation worries you — a 2×2 Fisher test is essentially free on a modern computer, so there is no reason to accept an approximation to save computation.
The controversy about Yates’s correction
Yates’s continuity correction shrinks each cell’s departure by 0.5 before squaring it:
The intent is to compensate for approximating a discrete statistic with a continuous distribution. R’s chisq.test() applies it by default to 2×2 tables, which is why the same data can give you different p-values in R and in some other software (on this page: 0.026 against 0.040).
The dispute is that it overcorrects. Simulate all three tests in a setting where the null hypothesis is true (both groups carry a true risk of 20%, 3000 replicates per point) and see how often each one declares significance. The ideal value is 0.05:
figures/scripts/B1-03-chi-square.R| Per-group size | Pearson (uncorrected) | Yates-corrected | Fisher exact |
|---|---|---|---|
| 10 | 0.030 | 0.006 | 0.006 |
| 15 | 0.053 | 0.010 | 0.019 |
| 20 | 0.048 | 0.019 | 0.022 |
| 30 | 0.052 | 0.026 | 0.026 |
| 50 | 0.049 | 0.024 | 0.024 |
| 80 | 0.051 | 0.034 | 0.037 |
| 120 | 0.048 | 0.030 | 0.030 |
| 200 | 0.048 | 0.034 | 0.034 |
The result is counter-intuitive but very consistent: the uncorrected Pearson chi-square already tracks 0.05 from about 15 per group upwards, while Yates and Fisher stay below the nominal value throughout — even at 200 per group they reach only 0.034 and 0.034. A type I error rate below the nominal level is not a bonus: it means you are giving away power you already paid for with your sample size.
This is one of the few places in statistics where the standard textbook advice and the simulation results do not line up. Pragmatically:
- State which version you used (uncorrected chi-square, Yates, or Fisher). Do not make the reader guess.
- When the sample is large enough (all expected counts at least 5), the uncorrected Pearson chi-square is a reasonable default.
- When the sample is small, Fisher is a safe choice — conservative, but conservative in the direction that does not manufacture false positives. At that point the real problem is usually a lack of power, not the choice of test.
- Whichever you pick, report the effect measure and its confidence interval. This whole argument moves the third decimal place of a p-value; it does not decide whether the OR is 2 or 20.
Paired categorical data needs McNemar
When the same people are measured twice (before and after treatment, two diagnostic tools compared, a matched case-control design), the data still look like a 2×2 table, but the cells mean something entirely different: each one now counts one person’s pair of results.
Take the classic example from R’s documentation (1600 respondents asked the same question at two time points):
| First survey \ Second survey | Approve | Disapprove |
|---|---|---|
| Approve | 794 | 150 |
| Disapprove | 86 | 570 |
The people on the diagonal — those who answered the same way twice — contribute nothing whatsoever to the question “did anything change”. All the information is in the two discordant cells: 150 people moved from approve to disapprove and 86 moved the other way. McNemar’s test uses only those two numbers:
which gives = 17.36, p = < 0.001. R’s mcnemar.test() applies a continuity correction by default — — so what it prints is = 16.82, p = < 0.001; the exact binomial version gives p = < 0.001. All three point the same way here, but the formula above is the uncorrected one, so check which version a paper is quoting before you try to reproduce it.
Hand the same table to a chi-square test as if the observations were independent and you get = 785.5, p = < 0.001 — an astronomically significant result, except that it tests a completely different null hypothesis (that a respondent’s first answer is independent of their second), and that hypothesis was absurd from the start: of course one person’s two answers are related. When a p-value comes back this extreme, asking “what is this test actually testing” usually finds the error faster than asking “how big is the difference”.
Common misuses
| Misuse | Why it is wrong |
|---|---|
| Reporting only the chi-square p-value, with no OR, RR or risk difference | The test answers “is there an association”; only an effect measure answers “how much”, and that is what the abstract needs |
| Judging usability from observed counts rather than expected counts | The rule is about expected counts; print $expected after chisq.test() |
| Remembering “expected count < 5” as an absolute law | Cochran’s original allowed 20% of cells below 5 with all of them at least 1; only a 2×2 collapses to “not one cell” |
| Using a chi-square test on patients measured twice | Paired data needs McNemar; chi-square counts one person as two independent observations |
| Treating an ordinal variable (stage I–IV) as nominal in a chi-square test | Discards the ordering and loses power; use a trend test (Cochran-Armitage) or an ordinal model |
| Running a chi-square test on every pair of groups without adjustment | Exactly the multiple comparisons problem that follows an ANOVA; the family-wise error rate inflates |
| Feeding percentages or rates to a chi-square test instead of counts | The test consumes counts; feeding it percentages silently sets the sample size to 100 |
| Reading “exact” in Fisher’s exact test as “more correct” | Exact refers to how the p-value is computed; the test is also conservative and gives up power |
| Saying “the two are unrelated” because p > 0.05 | Only that this study did not detect an association; with a small sample the confidence interval is usually too wide to exclude anything |
| Claiming causation from a significant chi-square test | Association is not causation; confounding and selection bias both produce significant contingency tables |
Reproducing every number on this page
/opt/homebrew/bin/Rscript figures/scripts/B1-03-chi-square.RRead the figure
The answer comes from the same statistical output that produced this page's figures, not from a number typed in beside them.
The risk of low birth weight among non-smokers is 25.2%, and the same table reports an OR of 2.02 and an RR of 1.61. Why are those two so far apart?
Show the answer and why
Correct answer: The RR is 1.61, and this outcome is anything but rare - an OR only approximates an RR when the outcome is rare, and here it visibly inflates the ratio of risks
An odds ratio and a risk ratio approximate each other only when the outcome is rare, and a risk of about a quarter is nowhere near rare, so 2.02 sits well above 1.61. An odds ratio is a ratio of odds, not of risks, and the denominator of odds is the non-events: the commoner the outcome, the more the odds stretch the gap. 2.01 is the conditional maximum likelihood estimate Fisher reports, a different estimator from the sample odds ratio rather than a different piece of software getting it wrong. Cohort studies and randomised trials can compute both risks and should report the RR; case-control studies fix the numbers of cases and controls by design, so risks cannot be computed and only an OR is available, as with a logistic regression coefficient. What usually lands hardest, though, is the absolute risk difference, because one relative risk means very different clinical events at a low and at a high baseline risk.
Restricting the analysis to one stratum (n = 26) drops the smallest expected count below 5. What does that mean?
Show the answer and why
Correct answer: The cell with an expected count of 4.2 is what makes the chi-square approximation unreliable - the rule looks at expected counts, not observed ones
The rule about expected counts of 5 governs how well the chi-square distribution approximates the statistic, not how good the data are. When expected counts are small the statistic has a discrete, jumpy distribution, and approximating it with a continuous curve goes wrong, so 4.2 is what decides the question and the observed counts are not. 23.1 belongs to the full table, and once the analysis is restricted this is a different table that the old figure cannot vouch for. The association of 0.3 does look larger than in the full table, but this stratum holds 26 people and the confidence interval for the odds ratio spans an order of magnitude: the sample cannot detect an association of any moderate size, and it is the width of the interval that says so, never the p value. The original Cochran rule was in fact looser than never below 5: all expected counts at least 1, with fewer than a fifth of cells below 5. A two-by-two table has fewer than a fifth of a cell to spare, which is how it collapsed into the version people recite.
1600 respondents answer approve or disapprove at two time points. Treating this paired table as an ordinary two-way table and running a chi-square test produces an enormous statistic. Which respondents does McNemar's test actually use?
Show the answer and why
Correct answer: Only those who changed their minds. 150 moved one way and fewer moved the other, and the test asks whether those two numbers are asymmetric
The diagonal of a paired table holds the people who gave the same answer twice, including the 794 who approved both times. They contribute nothing to whether opinion changed, because they appear on both sides and cancel out however you count. McNemar looks only at the two discordant cells: 150 one way, fewer the other, and it asks whether that pair is asymmetric. Treating all 1600 as two independent groups asks instead how far the proportion approving differs between the two occasions, and since pairing makes each person appear twice it inflates the sample size, which is why the statistic comes out absurdly large. Whenever you see the same patients before and after, the same eye, or a matched design, check that the analysis kept up.
Among smokers, 30 of 74 had a low birth weight baby; among non-smokers, 29 of 115. The chi-square test gives p = 0.0265. Which number most belongs in the abstract?
Show the answer and why
Correct answer: The absolute risk difference of 0.153, roughly fifteen extra low birth weight babies per hundred smoking mothers
A significant chi-square says only that there is an association; it says nothing about direction, strength or cause, so swapping one p value for another changes nothing. 0.040 comes from a different computation and still fails to say how much the risk rises. 0.161 is a measure of association running from zero to one with no direction, fine for description but hard to use clinically, because nobody knows how many babies 0.161 stands for. An absolute risk difference such as 0.153 lands, because one relative risk means completely different clinical events at a low and at a high baseline risk. Cohort studies and randomised trials should report a relative risk together with the absolute risk difference; case-control studies can report only an odds ratio.
On the same two-by-two table, uncorrected Pearson gives p = 0.0265, Yates gives 0.0396 and Fisher's exact test gives 0.0362. Someone argues that because it is called exact, its answer is the most correct.
Show the answer and why
Correct answer: 0.0362 is computed exactly rather than read off an approximating distribution, but it treats both margins as fixed and known
Exact refers to how the p value is computed - enumerated rather than read off an approximating distribution - and not to the answer being more correct. Fisher's test can be exact because it fixes both margins and enumerates every table consistent with them. In a design whose margins really are fixed that is natural, but this study recruited a group of mothers and only afterwards learned how many smoked, so the margins were random. Conditioning on something that did not need conditioning on costs conservatism, which is why 0.0362 lands between the uncorrected 0.0265 and the Yates 0.0396. Conservative is not the same as correct: a test that never rejects is the most conservative and the least useful. Nor is the smallest p value a reason to report it, which is just picking the most flattering number. All three land on the same side here, and what the abstract needs is an effect size.
Simulating two groups with identical true risks and recording how often each method declares significance: at 15 per group, uncorrected Pearson declares significance 0.053 of the time, Yates 0.010 and Fisher 0.019. What does that show?
Show the answer and why
Correct answer: The Yates rate of 0.010 is far below nominal - the correction pushes the type I error rate down too far and pays for it in power
The nominal level is what these three rates should line up with. The uncorrected 0.053 sits almost exactly on it, so this simulation shows no sign of Pearson manufacturing false positives in small samples. What departs from nominal is the two corrected methods: Yates at 0.010 and Fisher at 0.019, both far below. They are not more correct, they are more conservative, and conservatism is paid for in the number of patients needed to detect an association of the same size. 0.048 is the rate at n = 200, near enough identical to the small-sample 0.053, so the claim that Pearson grows more conservative with sample size points the wrong way too. When a decision rests on a small table, arguing over which p value to report matters far less than reporting the effect size with its confidence interval.
Chapters that use this method
Watch next
醫學統計 EP12 卡方檢定
醫學統計 EP15 RR vs OR
醫學統計 EP02 變數類型Sources and licences
This page is original writing