Field note · May 30, 2025
sched_dep_hour by origin: a 4% spread
Real group means for one column across 14 segments, and what the pooled average conceals.
Breaking sched_dep_hour down by origin on flight-delays, because the headline average is 13 and no segment is actually there.
SFO— mean 13, median 13 (551 rows)DFW— mean 13, median 13 (612 rows)DEN— mean 13, median 13 (556 rows)PHX— mean 13, median 13 (571 rows)LAX— mean 13, median 13 (598 rows)ATL— mean 13, median 13 (600 rows)
Top to bottom that is 13 against 12, a spread of 3.9%. The pooled average is 13.
select origin,
count(*) as rows,
round(avg(sched_dep_hour)::numeric, 2) as mean,
percentile_cont(0.5) within group (order by sched_dep_hour) as median
from flight_delays
group by 1
order by mean desc;The groups are close enough that the pooled average is a fair summary. That is worth confirming rather than assuming: the check costs one query and the failure mode is invisible.
Notice the mean and median columns disagree only slightly here. Always compute both in the group-by. The comparison between them per segment is free and tells you whether you are looking at a level difference or a tail difference.
This is the setup for Simpson's paradox — the case where every segment moves one way and the total moves the other.