29  Inference on Categorical Data

In the Dermagraft trial, \(30.0\%\) of patients treated with the engineered skin substitute healed within twelve weeks, against \(18.3\%\) of those given standard care alone. That is a difference of \(11.7\) percentage points. Randomization rules out confounding but not chance. Divide any set of patients into two arms and treat them identically, and the two healing rates will rarely come out exactly equal. The question is whether the observed difference is larger than chance could produce.

Each arm reduces to a rate: the mean of a \(0/1\) outcome, with variance \(p(1-p)\) (categorical data). Such a rate, computed from a sample of size \(n\), varies from sample to sample with standard error \(\mathrm{SE} = \sqrt{p(1-p)/n}\), and for large \(n\) it is distributed normally about the true rate (sampling distribution). These pieces combine into the hypothesis test. The test assumes the device does nothing, works out how the trial’s difference would then be distributed, and reads off the normal curve how often chance alone would produce a difference this large.

import numpy as np
import matplotlib.pyplot as plt
from math import erf, sqrt, gamma, pi

# Okabe-Ito colorblind-safe palette, used consistently across this chapter's figures.
BLUE, GOLD, GREEN, PURPLE = "#0072B2", "#E69F00", "#009E73", "#CC79A7"

# The standard normal CDF, Phi(z) = P(Z <= z), from the error function:
#     Phi(z) = (1/2) [ 1 + erf(z / sqrt(2)) ].
# This is the area tool the section reads p-values from -- the same normal curve
# the sampling section built, now used to turn a z-score into a tail probability.
def Phi(z):
    return 0.5 * (1.0 + erf(z / sqrt(2.0)))

def two_sided_normal_p(z):
    "Two-tailed p-value: the standard-normal area beyond |z| in both tails."
    return 2.0 * (1.0 - Phi(abs(z)))

Estimating a proportion: the confidence interval

The device arm’s healing rate, \(\hat p = 0.300\), is a single number. It is the best available guess at the true rate \(p\) among patients like these. But it is still a guess, built from \(130\) patients rather than every patient who might ever receive the device. A different \(130\) patients would have produced a different \(\hat p\) (sampling distribution). A point estimate alone gives no sense of how far off it might be. A confidence interval does: instead of reporting the single value \(\hat p\), it reports a range of values plausible enough to contain the true \(p\).

The range is built around the point estimate, using the same standard error. \(\hat p\) is approximately normal about \(p\), with standard error \(\mathrm{SE} = \sqrt{p(1-p)/n}\) (sampling distribution; here \(\hat p\) is substituted for the unknown \(p\) inside the square root). The normal distribution’s areas then say how far \(\hat p\) typically strays from \(p\). About \(95\%\) of the normal curve lies within \(1.96\) standard deviations of its center, so a 95% confidence interval for \(p\) is

\[ \hat p \;\pm\; 1.96 \times \mathrm{SE}, \qquad \mathrm{SE} = \sqrt{\frac{\hat p (1-\hat p)}{n}}. \]

This normal model needs the success-failure condition: \(n\hat p \ge 10\) and \(n(1-\hat p) \ge 10\). The patients must also be independent of one another. For the device arm, \(130 \times 0.300 = 39\) and \(130 \times 0.700 = 91\), both at least \(10\), so the normal model applies.

More generally, at any confidence level the interval takes the form

\[ \text{point estimate} \;\pm\; z^\star \times \mathrm{SE}, \]

Here \(z^\star\) is the normal cutoff for the chosen level (\(1.65\) for \(90\%\) confidence, \(1.96\) for \(95\%\), \(2.58\) for \(99\%\)), and \(z^\star \times \mathrm{SE}\) is called the margin of error. \(z^\star\) grows with the confidence level, so the interval widens as the required confidence rises.

What “95% confidence” means

The phrase invites a probability statement about the one interval just computed, and that reading is wrong. Before the sample is drawn, \(\hat p\) is a random quantity, and so is the interval built from it. The population parameter \(p\), by contrast, is a fixed number that does not change from sample to sample. Once a particular sample of \(130\) patients has been drawn and a particular interval computed, that interval either contains \(p\) or it does not. The “\(95\%\) confidence” label describes the procedure, not this one outcome of it: if the same sampling and interval-construction procedure were repeated many times over many samples, about \(95\%\) of the resulting intervals would contain the true \(p\). A simulation of that repetition draws \(25\) hypothetical samples of \(130\) patients from a population with the device arm’s own healing rate, and builds a \(95\%\) confidence interval from each (see Figure 29.1).

p_true, n_ci = 0.300, 130
zstar_95 = 1.96

rng = np.random.default_rng(1)
p_hats = rng.binomial(n_ci, p_true, size=25) / n_ci
se_hats = np.sqrt(p_hats * (1 - p_hats) / n_ci)
los, his = p_hats - zstar_95 * se_hats, p_hats + zstar_95 * se_hats
captures = (los <= p_true) & (p_true <= his)

print(f"{captures.sum()} of 25 simulated intervals capture the true rate p = {p_true}")
24 of 25 simulated intervals capture the true rate p = 0.3
Figure 29.1: Twenty-five simulated 95% confidence intervals, each built from its own sample of n = 130. One (orange) misses the true rate. Generated by scripts/03_statistics/08_inference_categorical/gen_inference_categorical.py.

Twenty-four of the \(25\) simulated intervals contain the true rate of \(30.0\%\). One, drawn from an unusually low sample, misses it entirely.

The Dermagraft interval

The device arm’s standard error, from \(\hat p = 0.300\) on \(n = 130\) patients, is \(\mathrm{SE} \approx 4.0\) percentage points. Substituting into the \(95\%\) formula gives the interval.

p_hat, n = 0.300, 130
se = np.sqrt(p_hat * (1 - p_hat) / n)
zstar = 1.96
moe = zstar * se

print(f"p_hat = {p_hat:.3f},  SE = {se*100:.1f} percentage points")
print(f"margin of error = {moe*100:.1f} percentage points")
print(f"95% CI = ({(p_hat-moe)*100:.1f}%, {(p_hat+moe)*100:.1f}%)")
p_hat = 0.300,  SE = 4.0 percentage points
margin of error = 7.9 percentage points
95% CI = (22.1%, 37.9%)

The device arm’s healing rate is estimated at \(30.0\%\), and the \(95\%\) interval runs from about \(22\%\) to \(38\%\). The interval is wide, nearly \(16\) percentage points across, because it is built from only \(130\) patients. A larger trial would narrow it, since the standard error shrinks as \(1/\sqrt{n}\) (sampling distribution).

The logic of a hypothesis test

A confidence interval answers “what is the plausible range for this one rate.” The Dermagraft trial asks a comparative question: not what the device arm’s rate is on its own, but whether it differs from the control arm’s. That question needs a hypothesis test, which uses the same standard-error machinery.

A hypothesis test assumes the device does nothing, then asks how likely the observed data would be under that assumption. The assumption of no effect is the null hypothesis, written \(H_0\). The claim it is set against, that there is an effect, is the alternative hypothesis, written \(H_1\). For the trial the two read:

  • \(H_0\): the device has no effect; the true healing rate is the same with it as without it, \(p_{\text{device}} = p_{\text{control}}\).
  • \(H_1\): the device changes the healing rate, \(p_{\text{device}} \neq p_{\text{control}}\).

The null hypothesis is a precise, quantitative statement: it pins the two population rates to a single common value. Under \(H_0\) the sampling-distribution machinery applies approximately. If the two rates are truly equal, the observed difference \(\hat p_{\text{device}} - \hat p_{\text{control}}\) is a sample statistic with a known sampling distribution, centered on zero and spread by a standard error. This distribution, computed under \(H_0\), is the null distribution. The test locates the trial’s actual difference within it and measures how far into its tail that difference falls.

The logic is asymmetric. A test can reject the null hypothesis, meaning the data are unlikely under \(H_0\). It cannot prove \(H_0\) true. A difference consistent with chance shows only that the trial did not rule chance out, not that the device is inert. That is why a positive result is phrased as rejecting \(H_0\) rather than accepting \(H_1\).

One-sided and two-sided alternatives

The alternative hypothesis comes in two forms, and the choice between them is made before the data are seen. A two-sided (or two-tailed) alternative, \(H_1: p_{\text{device}} \neq p_{\text{control}}\), tests for a difference in either direction: the device might help or harm. It counts a result as extreme when the difference is large and positive or large and negative. A one-sided (or one-tailed) alternative, \(H_1: p_{\text{device}} > p_{\text{control}}\), tests only for a difference in a pre-specified direction, and counts only differences in that direction as evidence.

The two-sided form is the default, and the more conservative: it reserves half of the allowed error for each tail, so it demands slightly stronger evidence to reach significance in the expected direction. A one-sided test is justified only when a difference in the opposite direction would hold no interest and would be treated exactly as no difference at all. Because a device found to be worse than standard care would also be of interest, the Dermagraft comparison is two-sided.

The significance level and the p-value

Two numbers turn “how far into the tail” into a decision: a threshold fixed in advance, and the probability actually observed.

The significance level, written \(\alpha\), is the threshold: the probability of a chance result that the investigator is willing to treat as too improbable to attribute to chance. It is chosen before the data are examined, and it fixes how strong the evidence must be. By long convention \(\alpha = 0.05\): a result is declared statistically significant when it is of a kind that would arise less than five percent of the time were the null hypothesis true. The value \(0.05\) is a convention. It traces to Fisher, who in 1925 called that value “convenient” for judging significance (Fisher 1925). The p-value is the observed probability. Stated precisely:

the p-value is the probability, computed under the assumption that the null hypothesis is true, of obtaining a result at least as extreme as the one actually observed.

The p-value is computed under \(H_0\): the null is granted for argument’s sake. “At least as extreme” means a tail, not a point. The p-value adds the probability of the observed difference and of every larger one. “Extreme” is counted in the tails the alternative admits: both, for a two-sided test.

The decision rule follows mechanically. If \(p \leq \alpha\), the null is rejected; the result is statistically significant. If \(p > \alpha\), the test fails to reject \(H_0\). The same rule can be stated on the z-scale. The critical value is the cutoff that a test statistic must exceed to reject \(H_0\): for a two-sided test at \(\alpha = 0.05\), the two tails beyond \(\pm 1.96\) hold \(5\%\) of the standard normal area, so \(|z| > 1.96\) is significant.

The p-value is easy to misread. It is not the probability that \(H_0\) is true. \(H_0\) is either true or false, and the p-value is computed by assuming it true. A large p-value does not show that \(H_0\) is true; it shows only that the trial gave no evidence against it. The p-value answers one question: if the device did nothing, how often would chance alone produce a difference at least this large?

ImportantKnowledge check

A trial reports a two-sided p-value of \(p = 0.04\) for the difference between a treated and a control group, tested at \(\alpha = 0.05\). Which of the following are correct?

  1. There is a \(4\%\) probability that the null hypothesis is true.
  2. If the treatment truly had no effect, a difference at least as large as the one observed would arise about \(4\%\) of the time.
  3. The result is statistically significant at the \(0.05\) level.
  4. There is a \(96\%\) probability that the treatment works.

(b) and (c) are correct. The p-value is the probability of a result at least as extreme as observed, computed under the null: that is exactly statement (b). Since \(0.04 \leq 0.05\) the null is rejected, so (c) holds.

(a) and (d) are wrong, and in the same way: both read the p-value as a probability about the hypotheses, when it is a probability about the data under an assumed null. Because the p-value assumes \(H_0\), it cannot report the probability that \(H_0\) is true (a), nor its complement, the probability that the treatment works (d).

Type I and Type II error

A hypothesis test returns a verdict, and a verdict can be wrong. Because the data are random, a test can reject a true null or fail to reject a false one. There are two errors, corresponding to the two ways truth and verdict can disagree:

  • A Type I error is rejecting a null hypothesis that is in fact true: declaring an effect where there is none, a false positive. Approving an inert device on the strength of a chance difference is a Type I error.
  • A Type II error is failing to reject a null hypothesis that is in fact false: missing an effect that is really there, a false negative. Dismissing a device that genuinely helps, because the trial happened not to reach significance, is a Type II error.

The significance level is exactly the rate of the first error. By setting \(\alpha = 0.05\), the investigator accepts that a true null will be wrongly rejected five percent of the time: run twenty trials of treatments that do nothing, and about one will cross the threshold by chance. The probability of a Type II error is written \(\beta\). Its complement, \(1-\beta\), is the probability of correctly detecting a real effect, and it is the test’s power.

# The two error rates as areas under two competing distributions. Under H0 the
# statistic centers on 0; under a specific alternative it centers on the true effect.
# A single decision threshold (the critical value) splits both curves -- shown here
# for a one-sided test at alpha = 0.05, so the whole shaded null tail is alpha.
effect = 3.0                       # true effect size, in standard errors, under H1
zc = 1.645                         # one-sided 0.05 critical value
x = np.linspace(-4, 7, 2001)
null = np.exp(-0.5*x**2) / np.sqrt(2*pi)
alt = np.exp(-0.5*(x - effect)**2) / np.sqrt(2*pi)

fig, ax = plt.subplots(figsize=(8, 4.2))
ax.plot(x, null, color=BLUE, lw=2, label="under $H_0$ (no effect)")
ax.plot(x, alt, color=GREEN, lw=2, label="under $H_1$ (a real effect)")
ax.fill_between(x[x >= zc], null[x >= zc], color=GOLD, alpha=0.7,
                label=r"Type I error ($\alpha$): reject a true $H_0$")
ax.fill_between(x[x <= zc], alt[x <= zc], color=PURPLE, alpha=0.45,
                label=r"Type II error ($\beta$): miss a real effect")
ax.axvline(zc, color="black", lw=1.2, ls=":", label=f"decision threshold (z = {zc})")
ax.set_xlabel("test statistic")
ax.set_ylabel("density")
ax.legend(fontsize=8, loc="upper right")
plt.show()
Figure 29.2: Type I error (α) and Type II error (β), as areas under the null and alternative distributions. Generated by scripts/03_statistics/08_inference_categorical/gen_inference_categorical.py.

The two errors cannot both be reduced at a fixed sample size. The decision threshold is a single cutoff (see Figure 29.2). Moving it to the right, which demands a larger statistic and a smaller \(\alpha\), shrinks the Type I area and enlarges the Type II area. Moving it to the left reverses the trade. The only way to reduce both at once is to enlarge the sample. The standard error narrows as \(1/\sqrt n\) (sampling distribution), which pulls the two distributions apart.

NoteThe two errors of a hypothesis test
\(H_0\) true (no effect) \(H_0\) false (real effect)
Reject \(H_0\) (declare an effect) Type I error (false positive, rate \(\alpha\)) correct (power, rate \(1-\beta\))
Fail to reject \(H_0\) correct, rate \(1-\alpha\) Type II error (false negative, rate \(\beta\))

The significance level \(\alpha\) is the false-positive rate the test is allowed; \(\beta\) is the false-negative rate; power \(1-\beta\) is the chance of catching a real effect.

The choice of \(\alpha\) sets how the unavoidable risk is split between false positives and false negatives. Setting \(\alpha = 0.05\) tolerates one false positive in twenty. Where a false positive is especially costly, \(\alpha\) is set lower: a definitive drug trial may demand \(0.01\) or less, and a screen that runs thousands of tests needs a far smaller threshold to keep the accumulated false positives in check. The right level depends on the relative cost of the two errors.

For the device, a Type I error would license an ineffective treatment: patients bear its cost and risk, while a wound that might have been managed otherwise goes untreated. A Type II error would shelve a device that genuinely heals, denying it to the patients it could help. The regulator requires a controlled trial, powered to detect a real benefit and judged at a pre-specified \(\alpha\), which holds both risks to a stated level.

ImportantKnowledge check

A screening test for a rare disease is tuned to a very small significance level \(\alpha\), so that it almost never flags a healthy person. Holding the study fixed, what does lowering \(\alpha\) do to the risk of missing a genuinely diseased person, and what single change to the study would reduce both errors at once?

Lowering \(\alpha\) shrinks the Type I rate (false alarms on healthy people) but raises the Type II rate (missed cases): demanding stronger evidence before flagging anyone means some true cases now fall short of the stricter bar. The two trade against each other at a fixed sample size. The one change that reduces both at once is to enlarge the sample, which narrows the sampling distributions (by \(1/\sqrt n\)) and separates the diseased and healthy curves, at a fixed \(\alpha\), lowering \(\beta\), at the cost of collecting more data.

Testing one proportion against a benchmark

The Dermagraft comparison sets two arms against each other. A single rate can also be tested against a benchmark \(p_0\). Here \(p_0 = 0.183\) is the null value, the healing rate under standard care. The device arm’s \(\hat p = 0.300\) is tested against it. The hypotheses are \(H_0: p = 0.183\) and \(H_1: p \neq 0.183\).

Under \(H_0\) the true rate is \(p_0\), so the standard error is computed from \(p_0\) rather than from \(\hat p\):

\[ \mathrm{SE}_0 = \sqrt{\frac{p_0(1-p_0)}{n}}, \qquad z = \frac{\hat p - p_0}{\mathrm{SE}_0}. \]

The normal model applies when the success-failure condition holds for \(p_0\): \(np_0 \ge 10\) and \(n(1-p_0) \ge 10\). Here \(130 \times 0.183 = 23.8\) and \(130 \times 0.817 = 106.2\), both at least \(10\).

For the device arm, \(\mathrm{SE}_0 = \sqrt{0.183 \times 0.817 / 130} = 0.0339\), so

\[ z = \frac{0.300 - 0.183}{0.0339} = 3.45, \qquad p = 2\,(1 - \Phi(3.45)) = 0.0006. \]

Since \(0.0006 < 0.05\), the null hypothesis is rejected: the device arm’s healing rate differs from the standard-care rate.

This test treats \(p_0\) as fixed, so it cannot account for variation in a second arm’s rate. The two-proportion z-test does.

When the conditions are not met

The normal model for \(\hat p\) needs independence and the success-failure condition. When the success-failure condition fails, the normal model is not accurate. A test can then use a null distribution found by simulation: draw many samples from a population with proportion \(p_0\), compute \(\hat p\) for each, and count the share at least as extreme as the observed \(\hat p\). The exact binomial probabilities from the binomial distribution give the same kind of answer for a single proportion.

When independence fails, the correction depends on how it fails. A cluster sample needs methods beyond this chapter. A convenience sample has no method that reliably corrects its bias, so its results need to be read with that bias in mind.

Choosing a sample size for a target margin of error

The confidence-interval formula runs in reverse to answer a design question asked before a trial ever enrolls a patient: how large must \(n\) be to pin down \(p\) to within a chosen margin of error \(E\)? Setting \(z^\star \mathrm{SE} \le E\) and solving for \(n\) gives

\[ n \;\ge\; \left(\frac{z^\star}{E}\right)^2 p(1-p), \]

using a planning estimate of \(p\) in place of the unknown true rate. A pilot or prior study often supplies one, such as the device arm’s own \(\hat p = 0.300\). If no estimate is available, use \(p = 0.5\). The product \(p(1-p)\) is largest at \(p = 0.5\), where it equals \(0.25\), so this choice gives the largest \(n\) for a given margin of error.

zstar, E, p_plan = 1.96, 0.05, 0.300     # target: 95% CI within +/- 5 percentage points
n_required = (zstar / E)**2 * p_plan * (1 - p_plan)
print(f"n >= {n_required:.1f}  ->  {int(np.ceil(n_required))} patients required")
n >= 322.7  ->  323 patients required

Tightening the margin of error from the trial’s actual \(\pm 7.9\) points to \(\pm 5\) points would require enrolling about \(323\) patients on the device arm alone, more than double the \(130\) actually studied.

Estimating the difference between two proportions

For two independent arms, the difference \(D = \hat p_1 - \hat p_2\) is approximately normal. Its standard error combines the two arms’ standard errors by the variances-add rule (numerical data):

\[ \mathrm{SE}_D = \sqrt{\mathrm{SE}_1^2 + \mathrm{SE}_2^2}, \qquad \mathrm{SE}_i = \sqrt{\frac{\hat p_i(1-\hat p_i)}{n_i}}. \]

The \(95\%\) confidence interval for \(p_1 - p_2\) is \(D \pm 1.96\,\mathrm{SE}_D\). Each arm’s own rate gives its standard error, since a confidence interval does not assume \(H_0\). For the Dermagraft trial, \(D = 0.300 - 0.183 = 0.117\) and \(\mathrm{SE}_D = 0.054\), so the interval is \(0.117 \pm 0.106\), or about \(1.2\) to \(22.3\) percentage points. The interval excludes zero.

Comparing two proportions: the z-test

The z-test expresses the observed difference between the two healing rates in standard errors. Under \(H_0\) both arms share one healing rate. The test therefore pools the two arms: the pooled proportion, estimated from all patients, gives the standard error of the difference and the success-failure check (sampling distribution).

NoteDerivation — the two-sample z-statistic

Write the two healing rates as sample proportions \(\hat p_1\) (device) and \(\hat p_2\) (control), measured on \(n_1\) and \(n_2\) patients. Each is the mean of a column of \(0/1\) outcomes, whose population variance is \(p_i(1-p_i)\) (categorical data). Its standard error and shape follow from the sampling distribution: for large \(n_i\),

\[ \hat p_i \;\approx\; N\!\left(p_i,\ \frac{p_i(1-p_i)}{n_i}\right), \qquad \mathrm{SE}_i = \sqrt{\frac{p_i(1-p_i)}{n_i}}. \]

The quantity of interest is the difference \(D = \hat p_1 - \hat p_2\). Its center is \(p_1 - p_2\), which the null hypothesis \(H_0: p_1 = p_2\) sets to zero. Its spread follows from the rule that the variances of independent quantities add (numerical data). The two arms are independent samples, so \(\mathrm{Var}(D) = \mathrm{Var}(\hat p_1) + \mathrm{Var}(\hat p_2)\). Subtraction adds the variances too. Under \(H_0\) both arms have one rate \(p\), so both variances use it:

\[ \mathrm{Var}(D) = \frac{p(1-p)}{n_1} + \frac{p(1-p)}{n_2} = p(1-p)\left(\frac{1}{n_1} + \frac{1}{n_2}\right). \]

The common \(p\) is unknown and is estimated by the pooled proportion \(\hat p = (x_1 + x_2)/(n_1 + n_2)\), which gives \(\mathrm{SE}_{\text{pool}} = \sqrt{\hat p(1-\hat p)(1/n_1 + 1/n_2)}\).

Because \(D\) is a difference of two approximately normal quantities, it too is approximately normal. Under \(H_0\) it is centered on zero with standard error \(\mathrm{SE}_{\text{pool}}\), so measuring it in standard errors yields a standard normal quantity, the test statistic

\[ z \;=\; \frac{D}{\mathrm{SE}_{\text{pool}}} \;=\; \frac{\hat p_1 - \hat p_2}{\mathrm{SE}_{\text{pool}}} \;\sim\; N(0, 1). \]

The z-statistic counts how many standard errors separate the two observed rates. The \(68\)–\(95\)–\(99.7\) rule (sampling distribution) says a value beyond \(\pm 2\) is uncommon under \(H_0\); the p-value makes “uncommon” exact, as the standard-normal area beyond \(|z|\) in both tails,

\[ p = 2\,\big(1 - \Phi(|z|)\big), \]

where \(\Phi\) is the standard normal CDF.

The device arm healed \(39\) of \(130\) patients, giving \(\hat p_1 = 0.300\); the control arm healed \(21\) of \(115\), giving \(\hat p_2 = 0.183\). The pooled proportion is \(\hat p = 60/245 = 0.245\), so \(\mathrm{SE}_{\text{pool}} = \sqrt{0.245 \times 0.755 \times (1/130 + 1/115)} \approx 0.0551\) and \(z = 0.1174/0.0551 \approx 2.13\). The success-failure condition holds under \(H_0\) with the pooled proportion: \(0.245 \times 130 = 31.9\), \(0.755 \times 130 = 98.1\), \(0.245 \times 115 = 28.2\), and \(0.755 \times 115 = 86.8\) are all at least \(10\).

# --- The Dermagraft trial, as a two-sample z-test of two proportions ---
x1, n1 = 39, 130          # device arm:  39 of 130 healed
x2, n2 = 21, 115          # control arm: 21 of 115 healed

p1, p2 = x1 / n1, x2 / n2                 # the two observed healing rates
diff = p1 - p2                            # the observed difference

# Under H0 both arms share one rate, so the test pools them for the standard error.
p_pool = (x1 + x2) / (n1 + n2)            # pooled healing rate, from all 245 patients
se_pool = np.sqrt(p_pool * (1 - p_pool) * (1/n1 + 1/n2))

z = diff / se_pool                        # test statistic: the difference in standard errors
p_value = two_sided_normal_p(z)           # two-tailed area beyond |z|

print(f"device  rate  p1 = {p1:.3f}")
print(f"control rate  p2 = {p2:.3f}")
print(f"pooled rate   p  = {p_pool:.3f}")
print(f"observed difference  p1 - p2 = {diff*100:5.1f} percentage points")
print(f"pooled SE of the difference  = {se_pool*100:5.1f} percentage points")
print(f"z-statistic           = {z:.2f}   (the difference is {z:.2f} standard errors wide)")
print(f"two-sided p-value     = {p_value:.3f}")
device  rate  p1 = 0.300
control rate  p2 = 0.183
pooled rate   p  = 0.245
observed difference  p1 - p2 =  11.7 percentage points
pooled SE of the difference  =   5.5 percentage points
z-statistic           = 2.13   (the difference is 2.13 standard errors wide)
two-sided p-value     = 0.033
# Visualize the p-value as the standard-normal area beyond |z| in both tails.
grid = np.linspace(-4, 4, 2001)
density = np.exp(-0.5 * grid**2) / np.sqrt(2 * np.pi)

fig, ax = plt.subplots(figsize=(7.5, 4))
ax.plot(grid, density, color=BLUE, lw=2)
right, left = grid >= z, grid <= -z
ax.fill_between(grid[right], density[right], color=GOLD, alpha=0.6)
ax.fill_between(grid[left], density[left], color=GOLD, alpha=0.6)
ax.axvline(z, color=GREEN, lw=2, label=f"observed z = {z:.2f}")
ax.axvline(-z, color=GREEN, lw=1.2, ls="--")
ax.axvline(1.96, color="0.5", lw=1, ls=":", label="±1.96 (significance at α = 0.05)")
ax.axvline(-1.96, color="0.5", lw=1, ls=":")
ax.set_xlabel("difference in standard errors (z)")
ax.set_ylabel("standard normal density")
ax.legend(fontsize=8, loc="upper left")
plt.show()
Figure 29.3: The Dermagraft z-test: the observed z = 2.13 against the standard normal, with the two-sided p-value shaded. Generated by scripts/03_statistics/08_inference_categorical/gen_inference_categorical.py.

The difference between the two arms is \(z = 2.13\) standard errors wide (see Figure 29.3), and the standard normal curve places about \(3\%\) of its area that far out or farther, in the two tails combined: \(p \approx 0.033\). At the conventional threshold \(\alpha = 0.05\), the result is significant: the observed \(z\) exceeds the critical \(\pm 1.96\), so the null hypothesis of no effect is rejected. Were the device inert, a healing-rate difference as large as the trial’s would arise from chance alone about three times in a hundred.

The trial reported \(P = 0.023\) for this comparison (Marston et al. 2003). Both analyses reject the null at \(0.05\), but the values differ, and the paper explains three differences from the calculation here.

The test. The trial used a slightly different test, Fisher’s exact test, which gives the reported \(P = 0.023\) on these counts.

The population. The trial enrolled \(314\) patients. The efficacy analysis covers the \(245\) with ulcers of six weeks’ duration. The paper states that this subgroup emerged at an interim analysis, after which the analysis plan was revised to a Bayesian sequential procedure. A subgroup identified from interim data makes the reported \(P\) optimistic.

The strata. Randomization was stratified by ulcer size, \(1\) to \(2\) cm\(^2\) and \(2\) to \(20\) cm\(^2\). This test ignores those strata. The paper adjusts for ulcer area and sex only in its analysis of time to closure.

Testing counts against a model: the chi-square goodness-of-fit test

The z-test compares two rates. Many categorical questions instead compare a whole table of counts against proportions fixed by some other source, such as a model, a regulation, or a known population, and no single rate captures that comparison. Suppose a multicenter trial enrolls \(240\) patients and records each patient’s blood type, and the trial’s statisticians want to know whether the enrolled blood-type distribution matches the distribution reported for the general population. The population figures are hypothetical, rounded for illustration, and are \(45\%\) type O, \(40\%\) type A, \(11\%\) type B, and \(4\%\) type AB, using the categories from data types. If enrollment were representative, the \(240\) patients should split across the four types in roughly those proportions. If it is skewed, the trial’s result may generalize poorly to the general population.

The expected count in each category is what representative enrollment predicts: the population proportion times the sample size. At \(n = 240\), the expected counts are \(0.45 \times 240 = 108\) type O, \(96\) type A, \(26.4\) type B, and \(9.6\) type AB. The enrolled counts are \(95\) type O, \(101\) type A, \(32\) type B, and \(12\) type AB. Each observed count differs from its expected count, and the question is whether the four differences, taken together, are larger than sampling variation alone would produce.

NoteDerivation — the chi-square statistic

Write the observed count in category \(i\) as \(O_i\) and the count expected under the model as \(E_i\). A single category’s standardized deviation, like the z-statistic, is \((O_i - E_i)/\sqrt{E_i}\): the discrepancy divided by the standard error a count of that size would have under simple random sampling. Squaring removes the sign, as squared deviations from the mean build the variance (numerical data). Summing the squared, standardized deviations across all \(k\) categories gives a single number that captures how far the whole table strays from the model at once:

\[ X^2 = \sum_{i=1}^{k} \frac{(O_i - E_i)^2}{E_i}. \]

This is Pearson’s chi-square statistic (Pearson 1900). It is zero only when every category matches its expected count exactly, and it grows without bound as any category’s observed and expected counts pull apart. Under the null hypothesis that the model’s proportions are correct, \(X^2\) follows the chi-square distribution with \(k - 1\) degrees of freedom. The counts must sum to the fixed total \(n\), so only \(k-1\) of them are free to vary (the same bookkeeping as the sample variance’s \(n-1\) in numerical data). The chi-square distribution is right-skewed and takes only positive values. Unlike the normal, only its upper tail counts as evidence against the null: a small \(X^2\) says the counts fit the model closely, and only a large \(X^2\) is surprising.

The approximation needs each expected count should be at least \(5\), so that the discrete counts behind \(X^2\) are well approximated by the continuous chi-square curve. Here the smallest expected count is \(9.6\), which is above that floor.

from math import gamma

def chi2_pdf(x, k):
    "Chi-square density with k degrees of freedom, from the gamma function."
    x = np.asarray(x, dtype=float)
    out = np.zeros_like(x)
    pos = x > 0
    out[pos] = (x[pos] ** (k / 2 - 1) * np.exp(-x[pos] / 2)) / (2 ** (k / 2) * gamma(k / 2))
    return out

def chi2_upper_tail_p(x_obs, k):
    "Upper-tail area of the chi-square distribution beyond x_obs, by integration."
    xs = np.linspace(x_obs, x_obs + 80, 400_000)
    return np.trapezoid(chi2_pdf(xs, k), xs)

labels = ["O", "A", "B", "AB"]
national_prop = np.array([0.45, 0.40, 0.11, 0.04])
n_enrolled = 240
observed = np.array([95, 101, 32, 12], dtype=float)   # sums to 240

expected = national_prop * n_enrolled
X2 = np.sum((observed - expected) ** 2 / expected)
dof = len(labels) - 1
p_value = chi2_upper_tail_p(X2, dof)

for lab, o, e in zip(labels, observed, expected):
    print(f"{lab:>2}: observed {o:5.0f}   expected {e:6.1f}   "
          f"(O-E)^2/E = {(o - e)**2 / e:6.3f}")
print(f"\nX^2 = {X2:.3f}   df = {dof}   p-value = {p_value:.3f}")
 O: observed    95   expected  108.0   (O-E)^2/E =  1.565
 A: observed   101   expected   96.0   (O-E)^2/E =  0.260
 B: observed    32   expected   26.4   (O-E)^2/E =  1.188
AB: observed    12   expected    9.6   (O-E)^2/E =  0.600

X^2 = 3.613   df = 3   p-value = 0.306
fig, axes = plt.subplots(1, 2, figsize=(10.5, 4))
xbar = np.arange(len(labels))
width = 0.35
axes[0].bar(xbar - width/2, observed, width, color=BLUE, label="observed")
axes[0].bar(xbar + width/2, expected, width, color=GOLD, label="expected (national)")
axes[0].set_xticks(xbar); axes[0].set_xticklabels(labels)
axes[0].set_xlabel("blood type"); axes[0].set_ylabel("number of patients")
axes[0].legend(fontsize=8)

grid = np.linspace(0.001, 16, 2001)
axes[1].plot(grid, chi2_pdf(grid, dof), color=BLUE, lw=2, label=f"chi-square, df = {dof}")
tail = grid >= X2
axes[1].fill_between(grid[tail], chi2_pdf(grid[tail], dof), color=GOLD, alpha=0.6,
                      label=f"p-value = {p_value:.3f}")
axes[1].axvline(X2, color=GREEN, lw=2, label=f"observed $X^2$ = {X2:.2f}")
axes[1].set_xlabel("$X^2$"); axes[1].set_ylabel("density")
axes[1].legend(fontsize=8)
plt.show()
Figure 29.4: Blood-type enrollment against the national distribution: observed vs. expected counts, and the chi-square goodness-of-fit test. Generated by scripts/03_statistics/08_inference_categorical/gen_inference_categorical.py.

The observed counts deviate from the national proportions in each of the four categories (see Figure 29.4), but deviations of this size are within what ordinary sampling variation produces: \(X^2 = 3.61\) on three degrees of freedom gives \(p = 0.306\), far above \(0.05\). The data give no evidence that the trial’s blood-type mix differs from the national distribution. Unlike the z-test, there is no single rate to report and no single standard error. There is a table of counts and one number, \(X^2\), that summarizes how far the whole table sits from the model.

Testing association between two categorical variables: the chi-square test of independence

The goodness-of-fit test asks whether one categorical variable matches a fixed model. A second, closely related question asks whether two categorical variables, both measured on the same individuals, are related at all: whether knowing one tells you anything about the other. The z-test treats all patients in each arm as one group, across all \(35\) centers. That treatment assumes healing does not depend on center. A chi-square test of independence checks that assumption.

Consider a hypothetical three-center trial, each enrolling \(100\) patients, with healing outcomes:

Healed Not healed Total
Center A \(40\) \(60\) \(100\)
Center B \(55\) \(45\) \(100\)
Center C \(45\) \(55\) \(100\)
Total \(140\) \(160\) \(300\)

If healing were independent of center, every center should show roughly the pooled rate, \(140/300 = 46.7\%\). The expected count in each cell of this two-way table comes from the table’s own row and column totals, not from an outside model:

\[ E_{\text{row},\,\text{col}} = \frac{(\text{row total}) \times (\text{column total})}{\text{table total}}. \]

For Center A’s “healed” cell, \(E = (140 \times 100)/300 = 46.7\); the same pooled rate applied to every center’s \(100\) patients. The chi-square statistic is built exactly as before, summing \((O-E)^2/E\) over every cell of the table, and its degrees of freedom for an \(r\)-row, \(c\)-column table are \((r-1)(c-1)\), here \((3-1)(2-1) = 2\).

centers = ["Center A", "Center B", "Center C"]
healed = np.array([40, 55, 45], dtype=float)
n_per_center = np.array([100, 100, 100], dtype=float)
not_healed = n_per_center - healed

table = np.vstack([healed, not_healed])                 # 2 rows (healed/not) x 3 columns (centers)
row_totals, col_totals = table.sum(axis=1), table.sum(axis=0)
expected_table = np.outer(row_totals, col_totals) / table.sum()

X2 = np.sum((table - expected_table) ** 2 / expected_table)
dof = (table.shape[0] - 1) * (table.shape[1] - 1)
p_value = chi2_upper_tail_p(X2, dof)

print("observed (healed row, not-healed row):\n", table)
print("expected:\n", np.round(expected_table, 2))
print(f"\nX^2 = {X2:.3f}   df = {dof}   p-value = {p_value:.3f}")
observed (healed row, not-healed row):
 [[40. 55. 45.]
  [60. 45. 55.]]
expected:
 [[46.67 46.67 46.67]
  [53.33 53.33 53.33]]

X^2 = 4.688   df = 2   p-value = 0.096
fig, axes = plt.subplots(1, 2, figsize=(10.5, 4))
rate = healed / n_per_center
axes[0].bar(centers, rate * 100, color=BLUE)
axes[0].axhline(healed.sum() / n_per_center.sum() * 100, color=GOLD, lw=2, ls="--",
                label="pooled healing rate")
axes[0].set_ylabel("healing rate (%)"); axes[0].legend(fontsize=8)

grid = np.linspace(0.001, 12, 2001)
axes[1].plot(grid, chi2_pdf(grid, dof), color=BLUE, lw=2, label=f"chi-square, df = {dof}")
tail = grid >= X2
axes[1].fill_between(grid[tail], chi2_pdf(grid[tail], dof), color=GOLD, alpha=0.6,
                      label=f"p-value = {p_value:.3f}")
axes[1].axvline(X2, color=GREEN, lw=2, label=f"observed $X^2$ = {X2:.2f}")
axes[1].set_xlabel("$X^2$"); axes[1].set_ylabel("density")
axes[1].legend(fontsize=8)
plt.show()
Figure 29.5: Healing rate by treatment center, and the chi-square test of independence between center and outcome. Generated by scripts/03_statistics/08_inference_categorical/gen_inference_categorical.py.

The three centers’ healing rates range from \(40\%\) to \(55\%\). The chi-square statistic, which measures this spread against chance alone, is \(X^2 = 4.69\) on two degrees of freedom, giving \(p = 0.096\) (see Figure 29.5). That is above the conventional \(\alpha = 0.05\), so the data give no evidence that healing depends on center, and pooling the centers is not contradicted. Had the p-value been small, center and outcome would not be independent, and a single pooled rate would be open to question.

When a contingency table has exactly two rows and two columns, the chi-square test of independence and the two-proportion z-test answer the same question: \(X^2\) from the chi-square test equals \(z^2\) from the (pooled) z-test on the same data. The chi-square framework is needed once a table grows past two-by-two, where no single z-statistic can summarize three or more groups at once but \(X^2\) still can.

ImportantKnowledge check

A goodness-of-fit test compares a sample’s category counts to a fixed model, and a test of independence compares two categorical variables measured on the same individuals. A hospital wants to know (i) whether its patients’ insurance-type mix (private, Medicare, Medicaid, uninsured) matches the mix reported for its county, and (ii) whether readmission (yes/no) is related to which of three wards a patient stayed on. Which chi-square test fits each question, and what are the degrees of freedom in each case?

  1. A goodness-of-fit test: one categorical variable (insurance type, four categories) is checked against an external model (the county’s reported mix), not against a second variable measured on the same patients. Degrees of freedom \(= k - 1 = 3\).

  2. A test of independence: two categorical variables, ward (three categories) and readmission (two categories), measured on the same patients, asking whether one predicts the other. Degrees of freedom \(= (r-1)(c-1) = (3-1)(2-1) = 2\).

The verdict on the device

The Dermagraft trial gave a difference in healing rates, \(30.0\%\) against \(18.3\%\). The hypothesis test asks how often chance alone would produce a difference this large if the device did nothing. The answer, about three times in a hundred, rejects that explanation at the conventional threshold: the difference is statistically significant.

That verdict rests on a chain of results: a rate is a mean, a mean has a sampling distribution, that distribution is normal with a standard error that shrinks as \(1/\sqrt n\), and a difference measured against that standard error can be graded by the normal curve into a p-value. What the p-value cannot establish is whether the trial was sound in the first place. A test grants the null its best case and weighs the data against it, but it takes the data as given: it cannot detect a trial in which the two groups differed from the start, or one in which knowing who received the device colored who was judged to have healed. Randomization and blinding make the p-value’s question valid. The chi-square test of independence lets a multicenter trial check, after the fact, whether pooling its centers was justified.

The categorical tests here cover healed or not, blood type, and center. A continuous outcome, such as how much an ulcer’s area shrank, needs its own version of this machinery (numerical inference).

Exercises

TipProblem 1

A trial of an antiseptic wound dressing reports that \(52\) of \(160\) ulcers healed on the dressing against \(34\) of \(160\) on standard gauze. Test, at \(\alpha = 0.05\) and two-sided, whether the dressing changes the healing rate.

  1. State \(H_0\) and \(H_1\) in terms of the two population rates.
  2. Compute the two observed rates, the pooled proportion, and the pooled standard error of the difference.
  3. Compute the z-statistic and the two-sided p-value, and state the conclusion.
  1. \(H_0: p_1 = p_2\) (the dressing does not change the healing rate); \(H_1: p_1 \neq p_2\).

  2. \(\hat p_1 = 52/160 = 0.325\) and \(\hat p_2 = 34/160 = 0.2125\). The pooled proportion is \(\hat p = 86/320 = 0.269\). The pooled standard error is \(\mathrm{SE}_{\text{pool}} = \sqrt{0.269\times0.731\times(1/160 + 1/160)} = 0.0496\).

  3. The difference is \(0.325 - 0.2125 = 0.1125\), so \(z = 0.1125/0.0496 = 2.27\). The two-sided p-value is \(2(1-\Phi(2.27)) \approx 0.023\). Since \(0.023 \leq 0.05\), reject \(H_0\): the dressing significantly changes (raises) the healing rate.

TipProblem 2

A pilot study of a new topical antibiotic finds that \(18\) of \(60\) treated wounds develop a mild irritation reaction, \(\hat p = 0.30\).

  1. Compute the standard error of this rate.
  2. Construct a \(95\%\) confidence interval for the true irritation rate.
  3. Construct a \(90\%\) confidence interval for the same data, and state which of the two intervals is wider, and why.
  1. \(\mathrm{SE} = \sqrt{0.30 \times 0.70 / 60} = \sqrt{0.21/60} = \sqrt{0.0035} \approx 0.0592\), or about \(5.9\) percentage points.

  2. \(95\%\) CI: \(0.30 \pm 1.96 \times 0.0592 = 0.30 \pm 0.116\), i.e. \((0.184,\ 0.416)\), or about \((18.4\%, 41.6\%)\).

  3. \(90\%\) CI: \(0.30 \pm 1.65 \times 0.0592 = 0.30 \pm 0.098\), i.e. \((0.202,\ 0.398)\), or about \((20.2\%, 39.8\%)\). The \(95\%\) interval is wider: a higher confidence level requires a larger \(z^\star\), which widens the margin of error for the same standard error.

TipProblem 3

A hospital wants to estimate the proportion of surgical-site infections after a new sterile-preparation protocol, to within a margin of error of \(E = 3\) percentage points at \(95\%\) confidence. A previous audit under the old protocol found an infection rate near \(8\%\), which is used as the planning estimate.

  1. Using \(p = 0.08\) as the planning value, compute the required sample size \(n\).
  2. Suppose instead no planning estimate were available. Explain, without computing, why using \(p = 0.5\) in the sample-size formula would give the largest possible required \(n\) for a fixed margin of error.
  3. Compute \(n\) under the conservative choice \(p = 0.5\), and compare it with part (a).
  1. \(n \ge (z^\star/E)^2\,p(1-p) = (1.96/0.03)^2 \times 0.08 \times 0.92 = 4268.4 \times 0.0736 \approx 314.2\), so \(n = 315\) patients.

  2. The factor \(p(1-p)\) is maximized at \(p = 0.5\), where it equals \(0.25\). Since \(n\) is proportional to \(p(1-p)\), using \(p=0.5\) produces the largest \(n\) consistent with any true rate, which is why it is the safe choice when the true rate is unknown.

  3. \(n \ge (1.96/0.03)^2 \times 0.25 = 4268.4 \times 0.25 \approx 1067.1\), so \(n = 1068\) patients: substantially more than the \(315\) required using the \(8\%\) planning estimate.

TipProblem 4

A two-sample comparison yields a z-statistic of \(z = 1.80\) in the direction the investigators hoped for.

  1. Compute the two-sided p-value.
  2. Compute the one-sided (upper-tail) p-value.
  3. At \(\alpha = 0.05\), state the conclusion under each of the two alternatives.
  4. A colleague, seeing that the two-sided test failed, proposes switching to the one-sided test to “get significance.” Explain in one or two sentences why this is illegitimate.
  1. Two-sided: \(2(1-\Phi(1.80)) \approx 0.072\).

  2. One-sided: \(1-\Phi(1.80) \approx 0.036\).

  3. Two-sided (\(p \approx 0.072 > 0.05\)): fail to reject \(H_0\). One-sided (\(p \approx 0.036 \leq 0.05\)): reject \(H_0\). The choice of alternative flips the decision.

  4. The direction of a one-sided test must be fixed before the data are seen, on the grounds that the opposite result would be of no interest. Switching to one-sided after seeing which way the data fell, to halve the p-value, chooses the test to suit the result. It inflates the true Type I error rate above the stated \(\alpha\) and is not a valid test.

TipProblem 5

The same healing-rate difference, \(30\%\) treated against \(18\%\) control, is observed at three trial sizes: \(15\) of \(50\) vs \(9\) of \(50\); \(30\) of \(100\) vs \(18\) of \(100\); and \(60\) of \(200\) vs \(36\) of \(200\) (all two-sided, \(\alpha = 0.05\)).

  1. For each, compute the z-statistic and the two-sided p-value (the difference is \(0.12\) in every case; only the standard error changes). Use the pooled proportion \(\hat p = 0.24\) in every case.
  2. At which sample sizes is the result significant?
  3. The rate difference is identical in all three. Explain, using the standard error’s dependence on \(n\), why the verdict nonetheless changes.
  1. With \(\mathrm{SE}_{\text{pool}} = \sqrt{0.24\times0.76\times(2/n)}\) and difference \(0.12\):
per-arm \(n\) \(\mathrm{SE}_{\text{pool}}\) \(z = 0.12/\mathrm{SE}_{\text{pool}}\) two-sided \(p\)
\(50\) \(0.0854\) \(1.40\) \(0.160\)
\(100\) \(0.0604\) \(1.99\) \(0.047\)
\(200\) \(0.0427\) \(2.81\) \(0.005\)
  1. Significant at \(n = 100\) and \(n = 200\) per arm (\(p \leq 0.05\)); not significant at \(n = 50\) (\(p = 0.160\)).

  2. The standard error of the difference shrinks as \(1/\sqrt n\), so as the sample grows the same \(0.12\) difference spans more and more standard errors (\(z\) rises from \(1.40\) to \(2.81\)), and the p-value falls.

TipProblem 6

Consider the Dermagraft z-test: \(\hat p_1 = 0.300\) (\(n_1 = 130\)) and \(\hat p_2 = 0.183\) (\(n_2 = 115\)). Under \(H_0\) with the pooled rate \(\hat p = 60/245 = 0.245\), the test gives \(z = 2.13\) and a two-sided p-value of \(0.033\).

  1. Compute the one-sided (upper-tail) p-value for this \(z\).
  2. Would a one-sided test have been legitimate for this trial? Explain.
  3. Compute the unpooled standard error of the difference, \(\mathrm{SE}_D = \sqrt{\mathrm{SE}_1^2 + \mathrm{SE}_2^2}\), where each arm uses its own observed rate. Then find the z-statistic it gives. Compare it with the pooled \(z = 2.13\) and the trial’s reported \(P = 0.023\): do they support the same conclusion?
  1. One-sided p-value \(= 1 - \Phi(2.13) \approx 0.017\) (half the two-sided value of \(0.033\), since the normal is symmetric).

  2. No, unless a worse-than-control outcome had been declared irrelevant in advance. A device that harmed patients relative to standard care would matter, so both directions are of interest and the two-sided test applies.

  3. Each arm’s own rate gives \(\mathrm{SE}_1 = \sqrt{0.300\times0.700/130} = 0.0402\) and \(\mathrm{SE}_2 = \sqrt{0.183\times0.817/115} = 0.0360\), so \(\mathrm{SE}_D = \sqrt{0.0402^2 + 0.0360^2} = 0.0540\). Then \(z = 0.1174/0.0540 = 2.17\), with two-sided p-value \(0.030\). The unpooled \(z = 2.17\) (p = 0.030), the pooled \(z = 2.13\) (p = 0.033), and the trial’s reported \(P = 0.023\) all have p-values below \(0.05\), so all three reject \(H_0\).

TipProblem 7

A drug-discovery lab screens \(400\) candidate compounds for an effect, running one hypothesis test per compound at \(\alpha = 0.05\). Suppose, for the sake of argument, that none of the \(400\) compounds actually has any effect. Testing many compounds at once raises the chance that at least one false positive appears in the whole screen. A multiple-comparisons correction lowers the threshold used for each test so that this overall chance stays small.

  1. How many “statistically significant” hits should the lab expect by chance alone?
  2. How many would it expect if it used \(\alpha = 0.01\) instead?
  3. A single compound comes back significant at \(p = 0.03\). Explain, using parts (a)–(b), why this alone is weak evidence that the compound works, and name one thing the lab should do next.
  1. Each true-null test has a \(5\%\) chance of a false positive, so the expected number is \(0.05 \times 400 = 20\) hits, purely by chance, from compounds that do nothing.

  2. At \(\alpha = 0.01\): \(0.01 \times 400 = 4\) expected false positives.

  3. When hundreds of tests are run, significant results appear by chance alone (about \(20\) of them here), so any one significant hit may be among the false positives, and a lone p-value of \(0.03\) does not separate it from noise. The lab should replicate the result, that is, repeat the experiment on fresh, independent samples, or apply a stricter, multiple-comparison-corrected threshold; an effect that reappears under replication is less likely to be chance. This is the multiple-comparisons problem: the per-test error rate is not the error rate of the screen as a whole.

TipProblem 8

A different clinic enrolls \(150\) patients and records each one’s blood type: \(58\) type O, \(70\) type A, \(16\) type B, and \(6\) type AB. Test, at \(\alpha = 0.05\), whether this clinic’s blood-type distribution is consistent with national proportions of \(45\%\) O, \(40\%\) A, \(11\%\) B, \(4\%\) AB.

  1. Compute the expected count in each category.
  2. Compute the chi-square statistic \(X^2\) and its degrees of freedom.
  3. The p-value for this \(X^2\) works out to \(0.389\). State the conclusion, and explain in one sentence what “expected count” means here: expected under what?
  1. Expected counts: O: \(0.45\times150 = 67.5\); A: \(0.40\times150=60\); B: \(0.11\times150=16.5\); AB: \(0.04\times150=6\).

  2. \(X^2 = \dfrac{(58-67.5)^2}{67.5} + \dfrac{(70-60)^2}{60} + \dfrac{(16-16.5)^2}{16.5} + \dfrac{(6-6)^2}{6} = 1.337 + 1.667 + 0.015 + 0 = 3.02\), on \(\mathrm{df} = 4-1=3\).

  3. At \(p = 0.389 > 0.05\), fail to reject \(H_0\): this clinic’s enrolled patients are consistent with the national blood-type distribution, and ordinary sampling variation can produce deviations of this size. “Expected” here means expected under the null hypothesis that this clinic’s population follows the national proportions exactly.

TipProblem 9

A trial enrolls patients at two centers and records, for each center, how many patients experienced a mild adverse skin reaction to a topical treatment: Center X, \(12\) of \(80\); Center Y, \(28\) of \(80\).

  1. Set up this as a \(2\times2\) table (reaction vs. no reaction, by center) and compute the expected count in each cell under the hypothesis that reaction rate is independent of center.
  2. Compute \(X^2\) and its degrees of freedom.
  3. A two-proportion z-test on the same two rates, using the pooled standard error, gives \(z = -2.92\). Compute \(z^2\) and compare it to your \(X^2\) from part (b). What general fact about \(2\times2\) tables does the comparison illustrate?
  1. Table:
Reaction No reaction Total
Center X \(12\) \(68\) \(80\)
Center Y \(28\) \(52\) \(80\)
Total \(40\) \(120\) \(160\)

Pooled reaction rate \(= 40/160 = 0.25\). Expected reaction count at each center: \(0.25 \times 80 = 20\); expected no-reaction count at each center: \(0.75\times80=60\).

  1. \(X^2 = \dfrac{(12-20)^2}{20} + \dfrac{(68-60)^2}{60} + \dfrac{(28-20)^2}{20} + \dfrac{(52-60)^2}{60} = 3.2 + 1.067 + 3.2 + 1.067 = 8.53\), on \(\mathrm{df}=(2-1)(2-1)=1\).

  2. \(z^2 = (-2.92)^2 = 8.53\), matching \(X^2 = 8.53\) exactly. This illustrates that for a \(2\times2\) table, the chi-square test of independence and the (pooled) two-proportion z-test are the same test: \(X^2 = z^2\).

NoteFurther reading

References

Adhikari, Ani, John DeNero, and David Wagner. 2022. Computational and Inferential Thinking: The Foundations of Data Science. 2nd ed. University of California, Berkeley (Data 8). https://inferentialthinking.com/.
Diez, David M., Mine Çetinkaya-Rundel, and Christopher D. Barr. 2019. OpenIntro Statistics. 4th ed. OpenIntro. https://www.openintro.org/book/os/.
Fisher, Ronald A. 1925. Statistical Methods for Research Workers. 1st ed. Oliver; Boyd.
Marston, William A., Jason Hanft, Paul Norwood, and Richard Pollak. 2003. “The Efficacy and Safety of Dermagraft in Improving the Healing of Chronic Diabetic Foot Ulcers: Results of a Prospective Randomized Trial.” Diabetes Care 26 (6): 1701–5. https://doi.org/10.2337/diacare.26.6.1701.
Pearson, Karl. 1900. “On the Criterion That a Given System of Deviations from the Probable in the Case of a Correlated System of Variables Is Such That It Can Be Reasonably Supposed to Have Arisen from Random Sampling.” The London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science 50 (302): 157–75. https://doi.org/10.1080/14786440009463897.