Unit 03.01: Name the grain before you summarise
'One row is one observation' sounds like a description of your data. It is actually a decision you make, and forgetting which one you made is how totals go wrong.
Name the grain before you summarise
The grain of a table is what one row represents. One ward-month. One ward. One visit. The same underlying facts can be arranged at any of these, and all the arrangements are correct — they just answer different questions.
Everything downstream depends on it. Averaging a column of ward-month rows gives a mean over ward-months, which is not the mean over wards unless every ward has the same number of months. Counting rows counts the grain, not the thing you had in mind.
str() and the tibble's own printout tell you the shape and the types. Only you can say what a row means.
This block shows the same six numbers arranged two ways.
suppressPackageStartupMessages(library(tibble))
# "One row is one observation" is a decision you make, not a fact of the data.
per_visit <- tibble(
ward = c("North", "North", "South", "South"),
month = c("Jan", "Feb", "Jan", "Feb"),
visits = c(412, 455, 388, 401)
)
cat("Shape:", nrow(per_visit), "rows x", ncol(per_visit), "columns\n")
cat("One row is: one ward in one month\n\n")
str(per_visit)
# The same numbers with a different observational unit:
per_ward <- tibble(ward = c("North", "South"),
jan = c(412, 388), feb = c(455, 401))
cat("\nSame data, one row per ward:", nrow(per_ward), "rows x",
ncol(per_ward), "columns\n")
cat("Neither is wrong. Say which one you are in before you summarise.\n")
The first table is 4 rows by 3 columns and one row is one ward in one month. str() confirms three columns and their types. The second holds the same information as 2 rows by 3 columns, one row per ward, with the months spread across columns. Neither is more correct; counting rows in the first gives ward-months and in the second gives wards.
The mistake this prevents
The mistake is computing an average over a table whose grain is finer than you assumed. Nothing errors, and the number is quietly a different quantity from the one in your report's sentence.
Takeaway
Before any summarise(), say out loud what one row is now and what one row should be afterwards. Use str() or glimpse() to confirm the shape, and write the grain into a comment.
