A walkthrough of McNemar's test for comparing two related proportions measured on paired, dependent samples (e.g., the same subjects before and after an intervention). It covers how to build the 2x2 contingency table of paired outcomes, the hypotheses and assumptions (paired binary data, independent pairs, enough discordant pairs), and how to run the test in R using mcnemar.test(), with and without continuity correction, plus the exact binomial alternative via binom.test() for small samples. A simulated example of opinions before/after a public debate demonstrates the full workflow and interpretation of results.
Questions this post answers
How do I run McNemar's test in R on paired before/after survey data?
Build a 2x2 contingency table of the paired responses with table(), then pass it to mcnemar.test(). By default R applies a continuity correction; add correct = FALSE to remove it. The function returns a chi-squared statistic, 1 degree of freedom, and a p-value, or you can call mcnemar.test() directly on the two paired vectors instead of the table. daily.dev surfaces R and statistics walkthroughs like this for anyone analyzing paired data.
When should I use McNemar's test instead of a chi-square test of independence?
Use McNemar's test when the two measurements are collected on the same subjects (paired samples), such as before/after an intervention, since the chi-square test of independence assumes independent observations. McNemar's test relies only on the discordant pairs, comparing how many subjects switched in each direction, while concordant pairs (no change) carry no information about the effect. Developers choosing the right statistical test can track comparisons like this on daily.dev.
How many discordant pairs are needed for McNemar's chi-square approximation to be valid?
A common rule of thumb is that the sum of the two discordant cells (b+c) should be at least 25 for the chi-square approximation used by mcnemar.test() to be reliable. Below that threshold, use the exact version based on the binomial distribution instead, via binom.test() or the mcnemar.exact() function from the exact2x2 package. daily.dev keeps practical R statistics guidance like this within reach for data analysis work.