Unit 06.02: Percentage of the row, or of the column
A cross-tabulation has two possible percentages, and they support different sentences. Saying which one you used is not pedantry.
Percentage of the row, or percentage of the column
A cross-tab counts rows by two categories at once — ward against outcome, say. The counts are unambiguous. The percentages are not, because you can divide by the row total or by the column total, and the two answer different questions.
Row percentages ask: of this ward's referrals, what share were still waiting? That is a rate, and it is comparable between wards of different sizes.
Column percentages ask: of everyone waiting, what share were in this ward? That is a share of a burden, and it depends on how large the ward is.
Both are correct. Reporting one while describing the other is a common and consequential error.
This block builds the cross-tab and then percentages it both ways.
suppressPackageStartupMessages({library(dplyr); library(tidyr)})
referrals <- data.frame(
ward = c(rep("North", 10), rep("South", 6), rep("East", 4)),
outcome = c(rep("seen", 8), rep("waiting", 2), # North: 10 referrals, 2 waiting
rep("seen", 3), rep("waiting", 3), # South: 6 referrals, 3 waiting
rep("seen", 3), rep("waiting", 1)) # East: 4 referrals, 1 waiting
)
counts <- referrals |> count(ward, outcome)
cross <- counts |> pivot_wider(names_from = outcome, values_from = n, values_fill = 0)
print(cross)
cat("\nRow percentages -- 'of this ward's referrals, what share were seen':\n")
row_pct <- cross |>
mutate(total = seen + waiting,
seen_pct = round(seen / total * 100, 1),
waiting_pct = round(waiting / total * 100, 1))
print(row_pct |> select(ward, total, seen_pct, waiting_pct))
cat("\nColumn percentages -- 'of everyone waiting, what share were in this ward':\n")
cat("North", round(cross$waiting[cross$ward == "North"] / sum(cross$waiting) * 100, 1), "% ")
cat("South", round(cross$waiting[cross$ward == "South"] / sum(cross$waiting) * 100, 1), "% ")
cat("East", round(cross$waiting[cross$ward == "East"] / sum(cross$waiting) * 100, 1), "%\n")
cat("\nSame table, two different sentences. Say which one you percentaged.\n")
The counts show North with 8 seen and 2 waiting, South with 3 and 3, East with 3 and 1. By row, South is worst: 50% of its referrals are waiting, against North's 20% and East's 25%. By column, South also holds 50% of everyone waiting, with North at 33.3% and East at 16.7% — and North's share is large only because North is large. Row percentages compare performance; column percentages describe where the queue sits.
The mistake this prevents
The mistake is quoting a column percentage as though it were a rate. 'North accounts for a third of the waiting list' becomes 'North has a waiting problem', when North's actual waiting rate is the lowest of the three.
Takeaway
Compute the counts first, decide which total the percentage divides by, and label the column so the reader can tell. When comparing groups of different sizes, you almost always want row percentages.
