Skip to content

12-01: Exercises — Chi-Square Goodness-of-Fit Test

Notes reference: 12-01: Chi-Square Goodness-of-Fit Test


Q1: Uniform goodness-of-fit

A spinner has 5 equal sectors. In 200 spins the results are: A 32, B 48, C 41, D 39, E 40. Is the spinner fair? Test at α = 0.05.

Solution

Sector O E O − E (O−E)²/E
A 32 40 −8 1.600
B 48 40 +8 1.600
C 41 40 +1 0.025
D 39 40 −1 0.025
E 40 40 0 0.000
Total 200 200 0 χ² = 3.250
STEP 1  H₀: the spinner is fair — each sector has probability 1/5
        H₁: at least one sector's probability differs
        α = 0.05

STEP 2  E = 200 × 1/5 = 40 for every cell;  all E ≥ 5  ✓
        df = k − 1 = 5 − 1 = 4

STEP 3  χ² = 3.250

STEP 4  critical χ²(0.05, 4) = 9.4877
        3.250 < 9.4877                    →  FAIL TO REJECT H₀
        p-value = P(χ²₄ > 3.250) = 0.5169 →  FAIL TO REJECT H₀

STEP 5  There is not sufficient evidence at the 5% level to conclude
        that the spinner is unfair.
=SUM(B2:B6)/5                       ' expected count = 40
=(B2-C2)^2/C2                       ' D2: cell contribution, fill down
=SUM(D2:D6)                         ' χ² -> 3.25
=CHISQ.INV.RT(0.05, 4)              ' 9.48773
=CHISQ.DIST.RT(3.25, 4)             ' 0.516851
=CHISQ.TEST(B2:B6, C2:C6)           ' p-value in one step -> 0.516851
obs <- c(A=32, B=48, C=41, D=39, E=40)
chisq.test(obs)
#  X-squared = 3.25, df = 4, p-value = 0.5169
chisq.test(obs)$expected            # 40 40 40 40 40
obs = np.array([32, 48, 41, 39, 40])
stats.chisquare(obs)                # statistic=3.25, pvalue=0.5169

Q2: Non-uniform goodness-of-fit

A company claims its customers split 50% Basic, 30% Standard, 20% Premium. A sample of 400 gives 178 Basic, 134 Standard, 88 Premium. Test at α = 0.05.

Solution

Plan O claimed p E = 400p (O−E)²/E
Basic 178 0.50 200 2.4200
Standard 134 0.30 120 1.6333
Premium 88 0.20 80 0.8000
Total 400 1.00 400 χ² = 4.8533
df = 3 − 1 = 2
critical χ²(0.05, 2) = 5.9915
4.8533 < 5.9915                       →  FAIL TO REJECT H₀
p-value = P(χ²₂ > 4.8533) = 0.0883    →  FAIL TO REJECT H₀

CONCLUSION: not sufficient evidence at the 5% level that the actual mix
differs from the claim. (Note it WOULD reject at α = 0.10 — a borderline
result worth revisiting with more data.)

CELL DIAGNOSTICS: the largest contribution is Basic (2.42), where 178
were observed against 200 expected. If the sample grows and the pattern
holds, "fewer Basic customers than claimed" is where the difference lies.
=400*C2                                     ' D2: expected = n × p
=(B2-D2)^2/D2                               ' E2: contribution
=SUM(E2:E4)                                 ' 4.85333
=CHISQ.DIST.RT(4.85333, 2)                  ' 0.088305
=CHISQ.TEST(B2:B4, D2:D4)                   ' same p-value
obs <- c(178, 134, 88)
chisq.test(obs, p = c(0.50, 0.30, 0.20))
#  X-squared = 4.8533, df = 2, p-value = 0.08831
obs = np.array([178, 134, 88])
exp = 400 * np.array([0.50, 0.30, 0.20])
stats.chisquare(obs, f_exp=exp)

Q3: A test that rejects

Historically, defects were distributed: Material 20%, Machine 35%, Operator 30%, Design 15%. After a process change, 250 defects are classified: Material 38, Machine 72, Operator 105, Design 35. Has the pattern changed? Test at α = 0.05.

Solution

Cause O p E (O−E)²/E
Material 38 0.20 50.0 2.8800
Machine 72 0.35 87.5 2.7457
Operator 105 0.30 75.0 12.0000
Design 35 0.15 37.5 0.1667
Total 250 1.00 250 χ² = 17.7924
df = 4 − 1 = 3
critical χ²(0.05, 3) = 7.8147
17.7924 > 7.8147                            →  REJECT H₀
p-value = P(χ²₃ > 17.7924) = 0.000487       →  REJECT H₀

CONCLUSION
    There is very strong evidence at the 5% level that the distribution
    of defect causes has changed.

WHERE THE CHANGE IS — read the contribution column:
    Operator  12.00   ← dominates:  105 observed vs. 75 expected
    Material   2.88          38 vs. 50 (fewer)
    Machine    2.75          72 vs. 87.5 (fewer)
    Design     0.17          essentially unchanged

    Operator-caused defects have risen sharply. The overall test says
    "something changed"; the contributions say WHAT changed — this is
    where the actionable finding lives.
obs <- c(Material=38, Machine=72, Operator=105, Design=35)
p   <- c(0.20, 0.35, 0.30, 0.15)
test <- chisq.test(obs, p = p)
test                                # X-squared = 17.792, df = 3, p = 0.0004866
round(test$expected, 1)
round(test$residuals^2, 3)          # the cell contributions
round(test$residuals, 3)            # SIGNED — shows direction

Q4: Expected counts too small

A survey of 40 people records favourite colour: Red 15, Blue 12, Green 8, Yellow 3, Purple 2. Test whether all colours are equally popular at α = 0.05.

Solution

E = 40/5 = 8 for every cell.

CONDITION CHECK:  all E = 8 ≥ 5  ✓   — the condition is on the EXPECTED
counts, not the observed ones, so Yellow (O = 3) and Purple (O = 2) are
not a problem here.

| Colour | O  | E | (O−E)²/E |
|--------|----|---|----------|
| Red    | 15 | 8 |  6.1250  |
| Blue   | 12 | 8 |  2.0000  |
| Green  |  8 | 8 |  0.0000  |
| Yellow |  3 | 8 |  3.1250  |
| Purple |  2 | 8 |  4.5000  |
|        | 40 |40 | χ² = 15.7500 |

df = 4,  critical χ²(0.05, 4) = 9.4877
15.75 > 9.4877                        →  REJECT H₀
p-value = 0.003383

CONCLUSION: colours are not equally popular. Red is over-represented and
Yellow/Purple under-represented.

NOW SUPPOSE n WERE 20 INSTEAD
    E = 20/5 = 4 < 5 for every cell  ✗   The condition FAILS.
    OPTIONS:
      1. Collect more data (always first choice).
      2. COMBINE categories: {Red}, {Blue}, {Green}, {Yellow + Purple}
         → k drops to 4, so df drops to 3. Recompute everything.
      3. Use an exact test (simulate the p-value):
             chisq.test(obs, simulate.p.value = TRUE, B = 10000)

Q5: Testing a Poisson fit

The number of calls per minute is recorded for 100 minutes:

Calls 0 1 2 3 4+
Frequency 14 30 27 18 11

Does a Poisson model fit? Estimate λ from the data and test at α = 0.05.

Solution

STEP 1  ESTIMATE λ from the data (treating "4+" as 4):
        λ̂ = [0(14) + 1(30) + 2(27) + 3(18) + 4(11)] / 100
          = [0 + 30 + 54 + 54 + 44] / 100 = 182/100 = 1.82

STEP 2  EXPECTED counts under Poisson(1.82), × 100:

        P(0) = e^(−1.82)                = 0.16203  →  E = 16.203
        P(1) = 1.82 e^(−1.82)           = 0.29489  →  E = 29.489
        P(2) = 1.82² e^(−1.82)/2        = 0.26835  →  E = 26.835
        P(3) = 1.82³ e^(−1.82)/6        = 0.16280  →  E = 16.280
        P(4+) = 1 − (sum of the above)  = 0.11193  →  E = 11.193
                                                       ───────
                                                       100.000  ✓

STEP 3  χ² = (14−16.203)²/16.203 + (30−29.489)²/29.489 + (27−26.835)²/26.835
           + (18−16.280)²/16.280 + (11−11.193)²/11.193
           = 0.29958 + 0.00885 + 0.00101 + 0.18175 + 0.00333
           = 0.49452

STEP 4  DEGREES OF FREEDOM — the key subtlety:
            df = k − 1 − (number of parameters ESTIMATED from the data)
               = 5 − 1 − 1 = 3
        because λ was estimated, not given.

        critical χ²(0.05, 3) = 7.8147
        0.49452 < 7.8147                  →  FAIL TO REJECT H₀
        p-value = P(χ²₃ > 0.49452) = 0.9199

STEP 5  The Poisson model with λ = 1.82 fits the data very well.

NOTE: a LARGE p-value here is the GOOD outcome — H₀ is "the model fits",
so failing to reject means the model survives. This is the one place in
the course where you WANT a big p-value.
obs    <- c(14, 30, 27, 18, 11)
counts <- 0:4
lambda <- sum(counts * obs) / sum(obs);  lambda        # 1.82

p <- dpois(0:3, lambda)
p <- c(p, 1 - sum(p))                                  # lump the 4+ tail
exp_counts <- 100 * p
round(exp_counts, 3)

chi <- sum((obs - exp_counts)^2 / exp_counts);  chi     # 0.4945
pchisq(chi, df = 5 - 1 - 1, lower.tail = FALSE)         # 0.9199

Q6: Chi-square test for a variance

A machine should produce parts with σ = 0.5 mm. A sample of 20 parts gives s = 0.68 mm. Test at α = 0.05 whether variability has increased.

Solution

STEP 1  H₀: σ ≤ 0.5        H₁: σ > 0.5        RIGHT-tailed,  α = 0.05

STEP 2  Requires the population to be NORMAL — check a Q-Q plot first.
        This test is NOT robust to non-normality.
        df = n − 1 = 19

STEP 3        (n − 1)s²      19 × 0.68²      19 × 0.4624      8.7856
        χ² = ───────────  = ────────────  = ────────────  =  ───────  = 35.1424
                 σ₀²           0.5²             0.25          0.25

STEP 4  critical χ²(0.05, 19) = 30.1435
        35.1424 > 30.1435                    →  REJECT H₀
        p-value = P(χ²₁₉ > 35.1424) = 0.01345

STEP 5  There is sufficient evidence at the 5% level that the process
        standard deviation exceeds 0.5 mm.

95% CI for σ (two-sided, for context):
        χ²(0.025, 19) = 32.8523      χ²(0.975, 19) = 8.9065
        σ² ∈ (8.7856/32.8523,  8.7856/8.9065) = (0.26743, 0.98643)
        σ  ∈ (0.517, 0.993) mm
        The interval lies entirely above 0.5 — consistent with the test.
=(20-1)*0.68^2/0.5^2                  ' 35.1424
=CHISQ.INV.RT(0.05, 19)               ' 30.14353
=CHISQ.DIST.RT(35.1424, 19)           ' 0.013452
=SQRT(8.7856/CHISQ.INV.RT(0.025,19))  ' 0.51714  lower bound for σ
=SQRT(8.7856/CHISQ.INV.RT(0.975,19))  ' 0.99320  upper bound for σ
n <- 20; s <- 0.68; sigma0 <- 0.5
chi <- (n-1)*s^2/sigma0^2;  chi                       # 35.1424
pchisq(chi, n-1, lower.tail = FALSE)                  # 0.013452
qchisq(0.95, n-1)                                     # 30.14353

Q7: Counts, not percentages

A student reports: "Observed percentages were 25%, 35%, 40%; expected were 33.3% each. My chi-square is 3.5, which is not significant."

What is wrong, and does it matter?

Solution

THE ERROR: the chi-square statistic must be computed from COUNTS, never
from percentages.

WHY IT MATTERS — the statistic scales directly with n. The same
percentages give completely different answers depending on sample size:

    Percentages:  25%, 35%, 40%   vs.  33.33% each

    n =  60  →  O = 15, 21, 24 ;  E = 20 each
                χ² = 1.25 + 0.05 + 0.80 = 2.10,  p = 0.350   NOT significant

    n = 300  →  O = 75, 105, 120 ; E = 100 each
                χ² = 6.25 + 0.25 + 4.00 = 10.50, p = 0.0052  SIGNIFICANT

    n = 900  →  χ² = 31.50,  p = 1.4 × 10⁻⁷     OVERWHELMING

The percentages are identical in all three. Only the EVIDENCE differs,
and evidence is exactly what the sample size buys.

Computing χ² from percentages implicitly assumes n = 100, which is a
number the student never checked.

ALWAYS: build the table in raw counts. Report percentages alongside for
readability, but feed COUNTS to the test.

Q8: Which test?

Name the test for each situation.

  1. Is a die fair? (60 rolls, 6 outcomes)
  2. Are gender and product preference related? (a 2 × 3 table)
  3. Do three hospitals have the same distribution of patient outcomes? (samples drawn separately from each)
  4. Does the process standard deviation exceed 2.0?
  5. Do observed blood-type frequencies match the known population percentages?

Solution

1. CHI-SQUARE GOODNESS-OF-FIT, uniform.  df = 6 − 1 = 5

2. CHI-SQUARE TEST OF INDEPENDENCE (12-02). df = (2−1)(3−1) = 2
   ONE sample, two variables recorded on each person.

3. CHI-SQUARE TEST OF HOMOGENEITY (12-02). Identical arithmetic to #2,
   but THREE separate samples with fixed row totals. The hypotheses are
   worded as "the three populations have the same distribution".

4. CHI-SQUARE TEST FOR A VARIANCE, right-tailed. df = n − 1.
   Requires normality and is not robust to it.

5. CHI-SQUARE GOODNESS-OF-FIT, non-uniform (E = n × known p).
   df = k − 1, with no subtraction because the p's came from outside
   the data, not estimated from it.

⬅️ Previous: 11-03: Exercises — Paired t-Test ➡️ Next: 12-02: Exercises — Chi-Square Test of Independence