Stats for

Categorical Data and Proportions

Cochran's Q

Cochran's Q compares yes/no proportions in the same people across conditions.

Cochran's Q takes a yes/no outcome measured in the same people under three or more conditions or at three or more times and tests whether the proportion answering yes is the same in all of them.

Example

Does the share of first-year students who often feel lonely change over their first year? Eighty first-year students answered yes or no to “In the past two weeks, have you often felt lonely?” in September, December and April, so each student has three answers.

Same People, Several Conditions + Binary Outcome → Cochran's Q
Tests
Differences among related population proportions
Observations
Related
Parametric
No
Headline Statistic
Q
Effect Size
Kendall's W
Groups
3+

The Basics

When to Use It

Use it when the same people give a yes/no answer under three or more conditions, or at three or more times, and you want to know whether the share answering yes is the same in all of them. It's McNemar's test extended past two measurements. For example:

  • Does the share of first-year students who often feel lonely change over their first year?
  • Do more participants solve an insight problem after a nap, after a quiet rest or after staying awake?
  • Do clients score above the GAD-7 cutoff for anxiety less often at 6, 12 and 24 weeks of treatment?

Vocabulary You Need

Definition Proportion (\hat{p})

The number of cases in a category divided by the total, such as the share of people who answered yes. It runs from 0 (none) to 1 (all), and multiplying by 100 turns it into a percentage. A sample proportion, written p̂ (“p-hat”), estimates the population proportion. If a yes/no outcome is coded 1 and 0, its mean is the proportion of 1s. Glossary →

Definition Chi-Square Statistic (\chi^2)

In a table test, for each cell, the squared gap between the observed and expected count, divided by the expected count, added up across all the cells. It is 0 when every count matches its expectation and grows as they drift apart. Other tests, such as likelihood-ratio tests that compare two models, also produce a χ², which grows with how much worse the more constrained model fits. Either way, it is compared with a chi-square distribution, the values it would take across many samples if the null hypothesis were true, to get a p-value; that distribution depends on the degrees of freedom, and its average equals them. It also grows with sample size, so it isn't a measure of how strong an effect is. Glossary →

Definition Omnibus Test

A single test of whether any of several groups differ, without saying which. A significant omnibus result is followed by comparisons of specific groups; a non-significant one doesn't prove the groups are equal. Glossary →

Definition Kendall's W for Cochran's Q (W)

A standardized omnibus index for Cochran's Q: Q divided by the largest value it can reach, N(k − 1), where N is the number of people and k the number of conditions. It is 0 when the share answering yes is the same in every condition, and 1 only when everyone gives the same pattern of answers and nobody gives the same answer throughout. It equals Kendall's W computed on the 0/1 answers: with the usual correction for ties, the Friedman χ² on 0/1 data equals Q, and W is the Friedman χ² divided by N(k − 1). People who answer the same way every time count in N but add nothing to Q, so the more of them there are, the smaller it gets. Some sources write it η²_Q; that notation isn't standard, and it isn't the ANOVA eta squared. Glossary →

Assumptions and Inference

1. Independent People (for the p-Value and Intervals) Different people are independent of one another, though each person's own answers are meant to be related.
What It Means
Each person's data comes from a separate, unconnected source, so knowing one person's scores tells you nothing about anyone else's. In designs that measure people more than once, their own scores are meant to be related; it's different people who must be independent. Methods built for clustered data, such as multilevel models and GEE, also allow members of the same group to be related, as long as the analysis names the grouping; then it's the groups that must be independent.
Applies To
Observations
How to Check
By design, not by a test. Did each person contribute their own data, with no clusters such as roommates, couples, therapy groups or classrooms whose members influence each other? If there are clusters, does the analysis model every one of them?
How Much It Matters
A lot. Each student's own three answers are meant to be related, but different students must not influence each other. If roommates answered together, their answers move together, and p comes out too small.

What to Do

  • Alternative Test Multilevel Logistic Regression. A multilevel logistic model with random effects for students and for the groups they belong to, such as residence halls.
  • Design Change Have each person answer on their own, so no one's answer can sway anyone else's.
2. Complete Data Every person has a score in every condition.
What It Means
The test compares conditions within each person, so it needs each person's full set of scores. Anyone missing a condition is dropped from the analysis entirely.
Applies To
Observations
How to Check
Count the people with a missing condition and ask why they're missing. If dropouts are more likely in one condition, dropping them can bias the result.
How Much It Matters
Depends on why answers are missing. Cochran's Q drops anyone missing even one time point. If who's missing is unrelated to loneliness (missing completely at random), you only lose power; if the loneliest students were the ones who skipped the April survey, dropping them would make loneliness look like it fell more than it did.

What to Do

  • Alternative Test Multilevel Logistic Regression. Keeps students with some missing time points and, if the model is right, stays unbiased when who drops out depends on answers you did see, such as loneliness in September (missing at random). It estimates change for a typical student.
  • Alternative Test Generalized Estimating Equations (GEE). A GEE logistic model uses every answer a student gave and can add covariates such as living on campus. Plain GEE is unbiased only if answers are missing completely at random; if dropout is related to how lonely students were, use weighted GEE or multiple imputation instead.
  • Proceed with Caveat Say how many people were dropped and at which time point, so readers can judge the risk.
3. Enough People Who Changed (for the Chi-Square p-Value) The chi-square p-value is an approximation built on the people whose answers vary. Exact or permutation p-values don't need a minimum.
What It Means
Cochran's Q uses only the people whose yes/no answer differs across the conditions; people who say yes every time, or no every time, don't affect it. Its chi-square p-value is an approximation that works best when more than a handful of people changed.
Applies To
Outcome
How to Check
Count the people who didn't give the same answer in every condition. If there are only a few, report an exact or permutation p alongside the chi-square one.
How Much It Matters
Q's p comes from a chi-square approximation. It works well when a fair number of people changed their answer, and less well with only a handful. When in doubt, report a permutation p as well. In the loneliness study 28 of the 80 students changed, and a permutation p (.017) is close to the chi-square p (.018).

What to Do

  • Correction Report an exact or permutation p, which doesn't rely on the chi-square curve (Patil, 1975). R's coin package gives a Monte Carlo permutation version.
  • Design Change Recruit more people. Only those whose answers vary carry information, so plan for how many you expect to change.
4. Similarly Related Time Points (for the p-Value) The usual p-value is most trustworthy when each pair of conditions is about as closely related, within people, as every other pair.
What It Means
Under the null hypothesis, the usual reference distribution treats each person's answers as interchangeable across conditions. That's a little more than equal proportions: it also implies every pair of conditions is about equally related within people. Mildly unequal relationships matter little, but if some pairs are much more alike than others, as neighboring time points often are, p can come out somewhat too small even when the proportions are equal, and a bigger sample doesn't fix it.
Applies To
Observations
How to Check
Look at how often people give the same answer in each pair of conditions, or the correlations between them. If one pair is much more alike than the others, check the result with a model that tests equal proportions alone.
How Much It Matters
Some, for p only. If one pair of time points is much more alike within students than the others, Q's p can be a little too small even when the proportions are equal. In the loneliness study the three pairs are about equally correlated (.50, .50 and .55), so it doesn't matter here.

What to Do

  • Alternative Test Generalized Estimating Equations (GEE). A GEE logistic model tests equal proportions on their own, without assuming the time points are equally related.
  • Proceed with Caveat Give how often students answered the same way in each pair of time points, so readers can see whether one pair stands out.

Limitations

This Is Not Your Test If…

What It Doesn't Tell You

  • Which times differ. A significant Q says the three proportions aren't all equal, not which ones differ. The pairwise McNemar tests and their intervals do that.
  • How many individuals changed. Q tests whether the overall proportions are equal across the times, not whether anyone changed their answer. Students could change repeatedly while the percentages stayed the same. Show the response patterns to describe individual change: here 28 of 80 students changed at least once.
  • Why. With no comparison group, the drop could come from settling in, from the loneliest students changing how they answer, or simply from the season.
  • Who else. The result describes first-year students like these 80, and only as well as one yes/no question captures loneliness.
  • That December and April are the same. They didn't differ reliably, but with only 16 students switching between them that's inconclusive, not evidence of no change.

Common Mistakes

  • Don'tTreat a larger Q as proof of a larger change.

    InsteadReport the percentage answering yes at each time and the percentage-point differences between the times you care about, with intervals. Q is an omnibus test statistic; it doesn't say how large any particular change was.

  • Don'tRun a chi-square test on the time-by-answer table as if each answer came from a different person.

    InsteadUse Cochran's Q, which keeps each person's answers together. The ordinary chi-square test counts the same students three times.

  • Don'tStop at a significant Q.

    InsteadFollow it with pairwise comparisons (exact McNemar tests with a discrete Holm adjustment) and report the proportions and differences with their intervals.

  • Don'tJudge W against Cohen's benchmarks for η² or Kendall's labels for agreement.

    InsteadJudge the size from the proportions and their differences. W also shrinks as more people give the same answer throughout.

  • Don'tDrop people who answered the same way every time before running the test.

    InsteadLeave them in. They don't change Q, but they count in N, the proportions and every interval.

  • Don'tCut a score into yes/no just to use Cochran's Q.

    InsteadAnalyze the scores themselves (a Friedman test or a repeated-measures model), unless the cutoff itself is the question. Cutting throws away information and power.

  • Don'tCompare W between studies where very different shares of people never changed their answer.

    InsteadCompare the proportions and their differences. W counts people who never changed in N, so it drops as they become more common.

  • Don'tRead a p-value as the chance that the null hypothesis is true.

    InsteadRead it as: if the null were true, how often data at least this extreme would turn up.

Result Decoder

Significance Guidelines

Benchmarks Significance (p Value)
  • p < .001

    Very strong evidence against the null hypothesis.

  • .001 ≤ p < .01

    Strong evidence against the null hypothesis.

  • .01 ≤ p < .05

    Statistically significant at α = .05. Moderate evidence against the null hypothesis.

  • .05 ≤ p < .10

    Not significant. Weak evidence; sometimes called a “trend.” Treat it as inconclusive.

  • p ≥ .10

    Not significant. Little evidence against the null, which is not the same as evidence of no effect.

These evidence labels are one common convention for describing p in graded language rather than as significant or not; the boundaries are rough guides, not rules, and other authors draw them differently. Muff et al. (2022) argue for this kind of language of evidence over a single cutoff. α is chosen before the analysis, and p never says how big or important an effect is.

More about statistical significance ↓

How It's Reported

Equation Form

Example

p̂Apr − p̂Sep = −.15, 95% CI [−.25, −.05]; Q(2) = 8.00, p = .018

Table 1. Students Who Often Felt Lonely at Each Time Point

Example
Yes\hat{p}95% CI
September 36.45[.35, .56]
December 28.35[.25, .46]
April 24.30[.21, .41]

Note. N = 80 students, each answering at all three time points. Intervals are Wilson score 95% CIs for each proportion.

Table 2. Pairwise McNemar Tests

Example
Yes → NoNo → YesDifferenceUnadjusted 95% CIExact pAdjusted p
September vs December 146−.10[−.21, .01].115.192
September vs April 164−.15[−.25, −.05].012.028
December vs April 106−.05[−.15, .05].454.454

Note. Yes → No counts students who said yes at the earlier time and no at the later one; No → Yes, the reverse. Difference = later proportion − earlier proportion, with a Wald 95% CI for paired proportions; the CIs are not adjusted for the three comparisons. p is the exact (binomial) McNemar test; adjusted p uses Westfall et al.'s (2010) discrete Holm adjustment across the three pairs.

Full Text (APA Style)

Example

In September, 45% of first-year students said they often felt lonely, 95% CI [35%, 56%]; by December 35% did, and by April 30% (Table 1). From September to April the share fell by 15 percentage points, 95% CI [5, 25]. Only 28 of the 80 students changed their answer at any point. Cochran's Q test showed that the proportions differed across the year, Q(2, N = 80) = 8.00, p = .018, Kendall's W = .05. Exact McNemar tests with a discrete Holm adjustment (Westfall et al., 2010) showed that fewer students felt lonely in April than in September (16 stopped feeling lonely and 4 started), adjusted p = .028; the other two pairs did not differ reliably (adjusted p = .192 and .454; Table 2).

  • Give each condition's proportion (or percentage) with its interval, and the differences that matter with theirs, before the test.
  • Report N and the degrees of freedom (k − 1) with Q, and name the test, since Q is judged against a chi-square distribution.
  • Follow a significant Q with pairwise McNemar tests, say which version (here exact), and name the correction (here the discrete Holm adjustment).
  • Say how many people changed their answer. They're the only ones Q uses; if there are few, add a permutation p (here .017).
  • Italicize Q, N, p and p̂, and give each p to three decimals rather than just "< .05".

Reading Each Piece

The equation form above, piece by piece, in this order: how big, how certain, then how surprising.

p̂Apr − p̂Sep = −.15 The share of students who often felt lonely fell by 15 percentage points between September and April, from 45% to 30%.
Kendall's W = .05 Q reached 5% of its ceiling, a small value of an omnibus index with no accepted benchmarks (Effect Size explains why it stays low). Judge the size from the 15-point drop instead.
95% CI [−.25, −.05] The true drop from September to April is plausibly anywhere from about 5 to 25 percentage points.
Q(2, N = 80) = 8.00 The yes counts are further from an even split than chance usually produces: with no real change, Q averages 2. The 2 in parentheses is the degrees of freedom, k − 1, and N = 80 is the number of students.
p = .018 If the share answering yes were the same at all three times, counts at least this uneven would turn up about 2% of the time. That's below .05, so the result is statistically significant. Benchmarks ↑

Calculations

The Running Example

Example

The loneliness study: 80 first-year students, each answering the same yes/no question about loneliness in September, December and April.

Null Hypothesis:
\pi_{\text{Sep}} = \pi_{\text{Dec}} = \pi_{\text{Apr}}
Alternative:
the three proportions are not all equal

\pi (“pi”) is the population proportion, the share of all first-year students like these who would say they often feel lonely at that point in the year. The sample's .45, .35 and .30 estimate them. The alternative doesn't say which time points differ or in which direction. Strictly, Q's p also assumes the three time points are about equally related to each other (see Statistical Significance).

What Your Data Should Look Like

One yes/no answer per person per condition, coded the same way throughout (here 1 = yes, 0 = no). Most software wants it wide: one row per person, one column per condition. Ours is stored long, one row per person per condition with columns for the person, the condition and the answer, and gets pivoted to wide for the test. Anyone missing a condition drops out.

Each student gives one of eight patterns of answers. Each three-digit pattern is one student's three answers in order, September, December, April, with 1 = yes: 100 means the student felt lonely in September but not in December or April, 111 means yes all three times and 000 no all three times. The loneliness study's 80 students:

Pattern 000 111 100 010 001 110 101 011
Students 36 16 10 4 2 6 4 2

The first two columns are the 52 students who gave the same answer every time. The other 28 changed at least once: 16 said yes once and 12 said it twice. Only these 28 feed into Q.

Example
studenttimelonely
1september1
1december0
1april0
2september0
2december0
2april0
… 234 more rows
nYes%
September803645.0%
December802835.0%
April802430.0%

Simulated data.

Download all 240 rows (data.csv)

Napkin Math

The whole test, one idea at a time. Under each heading, a line says why the step matters, and the green note reads the equation in plain English with the loneliness study's numbers. Collapse all to read just the headings: they tell the whole story on their own.

  1. 1. Count How Many Students Felt Lonely at Each Time Point

    Everything starts with how many students said yes each time. Divided by the 80 students, those counts are the three proportions the test compares.

    \hat{p} = \dfrac{x}{n} =\dfrac{36}{80},\quad \dfrac{28}{80},\quad \dfrac{24}{80}

    C_{\text{Sep}} = 36 students

    C_{\text{Dec}} = 28 students

    C_{\text{Apr}} = 24 students

    \hat{p}_{\text{Sep}} = .45

    \hat{p}_{\text{Dec}} = .35

    \hat{p}_{\text{Apr}} = .30

    x is the number who said yes, 36 in September, 28 in December and 24 in April; from here on we call each time point's count C. n is our 80 students, written N in the later steps. That's .45, .35 and .30, a steady slide over the year.

  2. 2. Work Out the Count We'd Expect If Loneliness Didn't Change

    If the share answering yes were the same at all three times, the yes answers would be spread evenly over the three time points, the same count at each.

    \bar{C} = \dfrac{\sum_{j=1}^{k} C_j}{k} =\dfrac{36 + 28 + 24}{3} = \dfrac{88}{3}

    = 29.33 students

    C_j is each time point's yes count and k our 3 time points. The 88 yes answers, shared evenly, give 88 ÷ 3 = 29.33 at each.

  3. 3. Set Aside Students Who Gave the Same Answer Every Time

    The test looks for differences among the three times. A student who said yes every time, or no every time, can't explain why September has more yes answers than April, but a student who said yes once and no twice can, because it matters which time got that yes. So, for Q only, students who never changed are set aside; they still count in the proportions and N. Weighting each student by how split their answers are drops them out automatically; R(k - R) is 0 for students who answered the same every time and bigger the more room a student's answers had to move.

    \sum_{i=1}^{N} R_i (k - R_i) =36(0)(3) + 16(1)(2) + 12(2)(1) + 16(3)(0)

    \text{students who changed} = 28 students

    \sum R_i(k - R_i) = 56

    R_i is how many times student i said yes. The 36 who never did and the 16 who always did count 0. The 16 who said yes once and the 12 who said it twice count 2 each, so the total is 32 + 24 = 56, from the 28 students who changed.

  4. 4. Compare How Far the Counts Stray with How Much Answers Could Vary

    Square each time point's gap from the even share and add them up, then divide by how much room students' answers had to move. Multiplying by k(k - 1) scales the result so that, with no real change, Q roughly follows a chi-square distribution with k − 1 df, which is what it's judged against.

    Q = \dfrac{k(k - 1)\sum_{j=1}^{k}(C_j - \bar{C})^2}{\sum_{i=1}^{N} R_i (k - R_i)} =\dfrac{3 \times 2 \times \left(6.67^2 + (-1.33)^2 + (-5.33)^2\right)}{56} = \dfrac{6 \times 74.67}{56}

    = 8.00

    \sum (C_j - \bar{C})^2 = 74.67

    September's 36 is 6.67 above 29.33, December's 28 is 1.33 below and April's 24 is 5.33 below. Squared and added, that's 74.67; times k(k - 1) = 3 × 2 = 6 it's 448, and 448 ÷ 56 = 8.00.

  5. 5. Account for How Much Information We Had

    The three counts' gaps from their average always add up to zero, so once two are known the third is fixed. df tells us which chi-square distribution to judge Q against.

    df = k - 1 =3 - 1

    = 2

    k is our 3 time points, not our 80 students. 3 − 1 = 2.

  6. 6. Measure How Big the Differences Are Overall

    Q grows with the number of people; this index doesn't. Dividing Q by the largest value it could reach gives Kendall's W for the 0/1 answers, a score from 0 (the same share every time) to 1.

    W = \dfrac{Q}{N(k - 1)} =\dfrac{8.00}{80 \times (3 - 1)}

    = .05

    Q is our 8.00, N our 80 students and k - 1 = 2. The largest Q could be is 80 × 2 = 160, and 8.00 ÷ 160 = .05.

  7. 7. Find How Much the Share Changed from September to April

    The overall test doesn't say how big any change is, so put a number on the one that matters most, the start of the year against the end. Students who answered the same both times cancel out.

    \hat{p}_2 - \hat{p}_1 = \dfrac{c - b}{n} =\dfrac{4 - 16}{80}

    = −.15

    b is the 16 students who felt lonely in September but not April, and c the 4 who went the other way. (4 − 16) ÷ 80 = −.15, the same as .30 − .45.

  8. 8. Give a Range of Plausible Values for That Change

    Instead of a single best guess, give the range of true changes that fit the data.

    (\hat{p}_2 - \hat{p}_1) \pm z^{*} \times \dfrac{\sqrt{(b + c) - (b - c)^2 / n}}{n} =-.15 \pm 1.96 \times \dfrac{\sqrt{20 - 144/80}}{80}

    = [−.25, −.05]

    z^{*} = 1.96 holds the middle 95% of a normal curve. The standard error is √(20 − 1.8) ÷ 80 = .053, and 1.96 × .053 = .10, so the range is −.15 ± .10, from −.25 to −.05.

  9. 9. Ask How Surprising the Result Would Be If Loneliness Didn't Change

    Finally, ask how often the three counts would land at least this far from an even split if the share answering yes were the same at all three times.

    p = P(\chi^2_{df} \ge \chi^2) =P(\chi^2_{2} \ge 8.00)

    = .018

    \chi^2_{2} is a chi-square distribution with 2 df. The chance it lands at or above 8.00 is .018, about 1 in 55. Only large values count against the null, so there's one tail, but it catches change in any direction.

Run It in Software

The code below reads the running example's data from data.csv; save it in the same folder you run the code from.

SPSS (version 30, as documented by IBM)
  1. SPSS wants one column per time point. Our file is long, so first use Data → Restructure → Restructure selected cases into variables, with student as the Identifier Variable and time as the Index Variable. You get one row per student with columns april, december and september (0 = no, 1 = yes).
  2. Analyze → Nonparametric Tests → Legacy Dialogs → K Related Samples.
  3. Move september, december and april into Test Variables. Under Test Type, uncheck Friedman, check Cochran's Q, and click OK.
  4. For the pairwise comparisons: Analyze → Nonparametric Tests → Legacy Dialogs → 2 Related Samples, add the three pairs, check McNemar, and click OK. Then adjust for the three pairs (below).

Or paste this syntax:

NPAR TESTS
  /COCHRAN=september december april
  /MISSING LISTWISE.

NPAR TESTS
  /MCNEMAR=september september december WITH december april april (PAIRED)
  /MISSING ANALYSIS.

Reading the Output

Read the Frequencies table first: the Value 1 row gives each time point's yes count (36, 28 and 24 of 80), so the proportions are .45, .35 and .30. Then read Cochran's Q, df and Asymp. Sig. SPSS doesn't print Kendall's W for Cochran's Q; work it out as 8.00 ÷ (80 × 2) = .05.

Frequencies

Value 0 Value 1
september 44 36
december 52 28
april 56 24

Test Statistics

N Cochran's Q df Asymp. Sig.
80 8.000ᵃ 2 .018

a. 1 is treated as a success.

With as few changers per pair as here (16 to 20), SPSS's McNemar tests use the exact binomial distribution, the version this page uses for the pairs: .115 for September–December, .012 for September–April and .454 for December–April. SPSS can't do the discrete Holm adjustment. Either copy the three pairs' counts into the R or Python code below (adjusted p = .192, .028 and .454), or apply the ordinary Holm correction by hand: sort the p-values from smallest to largest, multiply by 3, 2 and 1, and keep each at least as large as the one before, giving .0118 × 3 = .035, .1153 × 2 = .231, and .454. Ordinary Holm on exact p-values also keeps the familywise error rate at .05, just with less power. Only September versus April stays below .05 either way. Say which correction you used.

Output laid out from this page's computed results, not captured from a live run; labels and layout may differ slightly in your version.

R
library(DescTools)
library(coin)

lonely <- read.csv("data.csv")
lonely$time <- factor(lonely$time, levels = c("september", "december", "april"))
lonely$student <- factor(lonely$student)   # coin needs the person as a factor

# Share answering yes at each time point
tapply(lonely$lonely, lonely$time, mean)

# Cochran's Q
CochranQTest(lonely ~ time | student, data = lonely)

# Effect size: Q / (N(k - 1))
q <- CochranQTest(lonely ~ time | student, data = lonely)$statistic
unname(q) / (80 * (3 - 1))

# Permutation p (Monte Carlo, so it varies a little with the seed)
set.seed(2026)
pvalue(symmetry_test(lonely ~ time | student, data = lonely, teststat = "quadratic",
                     distribution = approximate(nresample = 100000)))

# Which pairs differ: exact McNemar tests with a discrete Holm adjustment
wide <- xtabs(lonely ~ student + time, data = lonely)   # one row per student
pairs <- list(c("september", "december"), c("september", "april"), c("december", "april"))
yes_no <- sapply(pairs, function(p) sum(wide[, p[1]] == 1 & wide[, p[2]] == 0))
no_yes <- sapply(pairs, function(p) sum(wide[, p[1]] == 0 & wide[, p[2]] == 1))
changed <- yes_no + no_yes
p_exact <- mapply(function(b, n) binom.test(b, n)$p.value, yes_no, changed)

# Chance, under the null, that a pair with n changers gives an exact p at or below `cut`
p_at_or_below <- function(n, cut) {
  attainable <- sapply(0:n, function(x) binom.test(x, n)$p.value)
  sum(dbinom(0:n, n, 0.5)[attainable <= cut * (1 + 1e-7)])
}
ord <- order(p_exact); p_adj <- numeric(3); running <- 0
for (j in seq_along(ord)) {
  still_in <- ord[j:3]
  step <- sum(sapply(still_in, function(i) p_at_or_below(changed[i], p_exact[ord[j]])))
  running <- max(running, min(1, step)); p_adj[ord[j]] <- running
}
data.frame(pair = sapply(pairs, paste, collapse = "-"), yes_no, no_yes, p_exact, p_adj)
september  december     april
     0.45      0.35      0.30

	Cochran's Q test

data:  lonely and time and student
Q = 8, df = 2, p-value = 0.01832

[1] 0.05
[1] 0.01662
99 percent confidence interval:
 0.01559668 0.01768961

                pair yes_no no_yes    p_exact      p_adj
1 september-december     14      6 0.11531830 0.19213104
2    september-april     16      4 0.01181793 0.02781677
3     december-april     10      6 0.45449829 0.45449829

rstatix::cochran_qtest(lonely, lonely ~ time | student) gives the same Q. The permutation p (.017) comes from 100,000 random rearrangements of each student's own three answers, so another seed gives a slightly different value; the interval under it shows how much. The discrete Holm adjustment (Westfall et al., 2010) steps through the pairs like Holm's, but instead of multiplying a p by the number of pairs left, it adds up each remaining pair's chance of an exact p that small. A pair with few changers often can't produce a small p at all, so it adds little. For ordinary Holm on the exact p-values instead, use p.adjust(p_exact, "holm").

Output from a real run: R 4.6.1 (DescTools 0.99.60, coin 1.4-5), run 2026-09-29.

Python
import pandas as pd
from scipy.stats import binom
from statsmodels.stats.contingency_tables import cochrans_q, mcnemar

lonely = pd.read_csv("data.csv")
wide = lonely.pivot(index="student", columns="time", values="lonely")
wide = wide[["september", "december", "april"]]

print(wide.mean())

result = cochrans_q(wide)
print(result)

n, k = wide.shape
print(result.statistic / (n * (k - 1)))

# Which pairs differ: exact McNemar tests with a discrete Holm adjustment
pairs = [("september", "december"), ("september", "april"), ("december", "april")]
tables = [pd.crosstab(pd.Categorical(wide[a], [0, 1]), pd.Categorical(wide[b], [0, 1]), dropna=False)
          for a, b in pairs]
changed = [t.iloc[1, 0] + t.iloc[0, 1] for t in tables]
p_exact = [mcnemar(t, exact=True).pvalue for t in tables]

def p_at_or_below(m, cut):
    """Chance, under the null, that a pair with m changers gives an exact p at or below cut."""
    return sum(binom.pmf(x, m, 0.5) for x in range(m + 1)
               if min(1, 2 * binom.cdf(min(x, m - x), m, 0.5)) <= cut * (1 + 1e-7))

order = sorted(range(len(pairs)), key=lambda i: p_exact[i])
p_adj, running = [0.0] * len(pairs), 0.0
for j, i in enumerate(order):
    step = sum(p_at_or_below(changed[r], p_exact[i]) for r in order[j:])
    running = max(running, min(1.0, step))
    p_adj[i] = running
print(pd.DataFrame({"p_exact": p_exact, "p_adj": p_adj}, index=[f"{a}-{b}" for a, b in pairs]))
time
september    0.45
december     0.35
april        0.30
dtype: float64
df          2
pvalue      0.018315638888734182
statistic   8.0
0.05
                     p_exact     p_adj
september-december  0.115318  0.192131
september-april     0.011818  0.027817
december-april      0.454498  0.454498

cochrans_q wants one row per person and one column per condition, so pivot turns the long file wide first. statsmodels' mcnemar runs the exact binomial version by default. Wrapping each column in pd.Categorical with both levels keeps every table 2 × 2, even when nobody changed in one direction.

Output from a real run: Python 3.9.6 (statsmodels 0.14.6, pandas 2.3.3, scipy 1.13.1), run 2026-09-29.

Impact

Effect Size

The clearest sizes for Cochran's Q are the ones readers can picture: each condition's proportion, and the differences between the pairs that matter, each with its interval. They're in percentage points, and they count everyone.

45% of students often felt lonely in September, 35% in December and 30% in April. From September to April that's a drop of 15 percentage points, 95% CI [5, 25] (Table 2 has every pair).

For a single number that sums up all the conditions at once, divide Q by the largest value it could reach, N(k − 1). The result is Kendall's W worked out on the 0/1 answers: it runs from 0 to 1 and doesn't grow just because more people took part, but it has no established benchmarks for Cochran's Q, so the proportions and their differences stay the main measures of effect size. Some sources call this index η²Q; that notation isn't standard, and it isn't the ANOVA η². The link to W follows from two facts: with the usual correction for tied ranks, the Friedman test's χ² on 0/1 data equals Q exactly, and W, the Friedman test's effect size, is that χ² divided by N(k − 1) (Tomczak & Tomczak, 2014, p. 24).

W = \dfrac{Q}{N(k - 1)} = \dfrac{8.00}{80 \times 2} = .05

If every student whose answer changed had changed in exactly the same way, and nobody had given the same answer all year, Q would have hit its ceiling of 160 and W would be 1. Ours reached 8 of that 160. The 52 students who answered the same way all three times count in N but can't add anything to Q, so they cap W at 28 ÷ 80 = .35. The rest of the gap is the 28 who changed not all changing the same way: among them alone, Q reached 8 ÷ 56 = 14% of its ceiling.

W can't go below 0, so it's above 0 even when nothing changes: with no real change, Q averages k − 1, so W averages about 1 ÷ N (.0125 here). Small values in small samples mean little.

All of this is why W is hard to read on its own. Don't borrow Cohen's labels for η², or the agreement labels used for Kendall's W with rankings. Whether 15 fewer students in every 100 feeling lonely by spring is a meaningful change is a question for student wellbeing, not statistics.

There are no established benchmarks for this index specific to Cochran's Q, so there are none here; neither Cohen's conventions for η² nor Kendall's W's agreement labels carry over. Judge the size from the proportions and the differences between them.

Statistical Significance

p answers one narrow question: if the share answering yes were the same at all three times, so that each student's yes answers could just as easily have fallen at any of the three time points, how often would the yes counts spread at least this far from an even split? Only a large Q counts against the null, so p comes from one tail of the chi-square distribution, but it responds to differences in any direction. Below the conventional α = .05, the result is called statistically significant.

Strictly, that's a stronger null than equal proportions: it also assumes the three time points are about equally related to each other (see Assumptions and Inference). In the loneliness study they are (.50, .50 and .55), so it doesn't matter here.

If the share answering yes were the same at all three times, counts at least as uneven as 36, 28 and 24 would turn up about 1.8% of the time, roughly 1 in 55. That's below .05, so it's significant.

That p comes from the chi-square approximation, which is what SPSS, R and Python report by default. Only people whose answers vary feed into Q (Tate & Brown, 1970), so the approximation depends on how many of them there are, not on the total sample. With only a handful of changers, use an exact or permutation p, which works out the null distribution directly by rearranging each person's own answers (Patil, 1975). That removes the chi-square approximation, not the assumptions: rearranging a person's answers assumes they're interchangeable across the time points under the null, the same stronger null as above.

28 of our 80 students changed their answer. A permutation p from R's coin package is .017, next to the chi-square .018, so here the approximation is fine.

p is not the probability that the null hypothesis is true, and it says nothing about how large the changes are or which time points differ. That's what the proportions, their differences and the pairwise comparisons are for.

Benchmarks p at a Glance
Very Strong
p < .001
Strong
.001 ≤ p < .01
Significant
.01 ≤ p < .05
Weak
.05 ≤ p < .10
Little
p ≥ .10

Strength of evidence against the null hypothesis.

Full benchmarks and caveats ↑

Power and Sample Size

Power is the chance that a study detects an effect that's really there. A real effect doesn't guarantee a significant result: with too few people, it can easily come out non-significant. For Cochran's Q, power depends on how far apart the true proportions are, on α, and above all on how many people change their answer. People who give the same answer every time add nothing to Q, so a study where few people change needs a lot of people.

There's no simple formula for Cochran's Q's power, so this page has no calculator. The dependable way is simulation: write down how often you expect each pattern of answers (never yes, always yes, yes only in September, and so on), generate thousands of pretend studies, and count how often the test comes out significant.

As a planning example, suppose the true answer patterns in the next cohort were like the loneliness study's. We simulated that in R: 20,000 pretend studies at each size, each student independently drawing one of the eight answer patterns with the loneliness study's shares, and Q judged against the chi-square curve at α = .05. With 80 students, about 73% of studies came out significant; with 100 students, about 83%.

Don't compute power from your own completed study's estimates. That "observed power" just restates its p and adds nothing (Hoenig & Heisey, 2001). Our patterns are also a noisy estimate from 80 students, so when planning, try a smaller drop, or fewer changers, too.

Researchers usually aim for at least 80% power. Plan it before collecting data, using the smallest change that would matter.

Other Info

Follow-Up and Post Hoc Tests

Planned Contrasts

  • Planned Contrasts: Use when you predicted one specific comparison before collecting data, such as the first time point against the last. Test it with a single McNemar test, whether or not Q is significant; with more than one planned comparison, correct with Holm. In the loneliness study, September against April gives exact p = .012. If the conditions are ordered, like time points, and you expect change in one direction, a trend test (a GEE logistic model with time entered as a number) asks that one question, usually with more power than Q.

Post Hoc Tests

  • Pairwise McNemar Tests: Use to compare every pair after a significant Q. Each pair gets its own exact (binomial) McNemar test on the same people, then Westfall et al.'s (2010) discrete Holm adjustment, which counts how small a p each pair's exact test could actually produce. It keeps the familywise error rate at α in any sample size and, in their simulations, had more power than the common shortcut of ordinary Holm on large-sample McNemar p-values, which controls the error rate only approximately. They also describe a bootstrap step-down method, which they prefer in large samples because it accounts for how the pairs are correlated. In the loneliness study only September versus April differed, adjusted p = .028; September versus December, p = .192; December versus April, p = .454. The pairwise 95% intervals in Table 2 aren't adjusted for the three comparisons, so they won't always agree with the adjusted p-values.

References

  • Cochran, W. G. (1950). The comparison of percentages in matched samples. Biometrika, 37(3–4), 256–266. https://doi.org/10.1093/biomet/37.3-4.256
  • Tate, M. W., & Brown, S. M. (1970). Note on the Cochran Q test. Journal of the American Statistical Association, 65(329), 155–160. https://doi.org/10.1080/01621459.1970.10481069
    “rows containing only 1's or only 0's, i.e., only successes or only failures, do not affect the value of Q” (Abstract)
  • Patil, K. D. (1975). Cochran's Q test: Exact distribution. Journal of the American Statistical Association, 70(349), 186–189. https://doi.org/10.1080/01621459.1975.10480285
    “A relatively simple method for computing the exact probability and distribution of the Q statistic is proposed.” (Abstract)
  • McNemar, Q. (1947). Note on the sampling error of the difference between correlated proportions or percentages. Psychometrika, 12(2), 153–157. https://doi.org/10.1007/BF02295996
  • Holm, S. (1979). A simple sequentially rejective multiple test procedure. Scandinavian Journal of Statistics, 6(2), 65–70. https://www.jstor.org/stable/4615733
  • Westfall, P. H., Troendle, J. F., & Pennello, G. (2010). Multiple McNemar tests. Biometrics, 66(4), 1185–1191. https://doi.org/10.1111/j.1541-0420.2010.01408.x
    “Bonferroni-Holm with the ordinary McNemar (large sample) test and with the exact McNemar p-values are inferior methods.” (Section 10, Conclusion)
  • Hoenig, J. M., & Heisey, D. M. (2001). The abuse of power: The pervasive fallacy of power calculations for data analysis. The American Statistician, 55(1), 19–24. https://doi.org/10.1198/000313001300339897
    “This approach, which appears in various forms, is fundamentally flawed.” (Abstract)
  • Tomczak, M., & Tomczak, E. (2014). The need to report effect size estimates revisited. An overview of some recommended measures of effect size. Trends in Sport Sciences, 21(1), 19–25. https://tss.awf.poznan.pl/The-need-to-report-effect-size-estimates-revisited-An-overview-of-some-recommended,188960,0,2.html
    “Also, for the Friedman test, a non-parametric statistical test employed to compare three or more paired measurements (repeated measures), an effect size estimate can be calculated (and is referred to as W)” (p. 24)
  • Muff, S., Nilsen, E. B., O'Hara, R. B., & Nater, C. R. (2022). Rewriting results sections in the language of evidence. Trends in Ecology & Evolution, 37(3), 203–210. https://doi.org/10.1016/j.tree.2021.10.009
    “we suggest language of evidence that allows for a more nuanced approach to communicate scientific findings as a simple and intuitive alternative to statistical significance testing” (Abstract)

Spot an error? Something still confusing? Tell us at support@statsforpsychology.com.