Unit 06.03: The test detects; the residuals explain
A chi-square test tells you that two categorical variables are associated. It will not tell you how, and the residuals will.
The test detects; the residuals explain
A chi-square test of independence compares the observed counts in a contingency table with the counts expected if the two variables were unrelated. A large statistic means the table does not look like independence.
That is all it says. It gives no direction, no effect size and no indication of which cells are responsible. The standardised residuals do all three: each says how far that cell sits from its expected count, in standard units, with the sign giving the direction.
The one assumption to check is that expected counts are not too small — the usual rule of thumb wants every expected count above 5. Below that, use Fisher's exact test.
This block tests plan against churn and then inspects the residuals.
outcomes <- matrix(c(120, 80, 95, 105, 60, 140), nrow = 3, byrow = TRUE,
dimnames = list(plan = c("basic", "standard", "premium"),
churned = c("no", "yes")))
print(outcomes)
test <- chisq.test(outcomes)
cat("\nX-squared =", round(test$statistic, 3), " df =", test$parameter,
" p =", signif(test$p.value, 4), "\n\n")
cat("Expected counts under independence:\n")
print(round(test$expected, 1))
cat("\nStandardised residuals -- where the association actually is:\n")
print(round(test$residuals, 2))
cat("\nThe test says the plan and churn are associated. It does not say how,\n")
cat("and it does not say which direction. The residuals do: premium churns\n")
cat("far more than independence predicts, basic far less.\n")
cat("Smallest expected count:", round(min(test$expected), 1),
"-- the rule of thumb wants every expected count above 5.\n")
The test gives X² = 36.587 on 2 degrees of freedom, p = 1.135e-08 — plan and churn are associated. The residuals say how: premium sits at +3.04 on churn and −3.31 on no-churn, basic at −2.72 and +2.96. Premium churns far more than independence predicts and basic far less. The smallest expected count is 91.7, comfortably above the rule of thumb.
The mistake this prevents
The mistake is reporting the p-value and stopping. It says only that something is going on, and every actionable part of the finding is in the residuals.
Takeaway
Report the test, the expected counts and the standardised residuals together. Check the smallest expected count, and switch to Fisher's exact test when it falls below about 5.
