library(tidyverse) library(NHANES) data(NHANES) heights <- NHANES |> filter(!is.na(Height)) |> select(Gender, Height) # ── ATTEMPT 1: summarize() with a multi-value function ────────────────────── # quantile() returns 5 numbers per group. # summarize() expects exactly ONE value per group → ERROR. heights |> group_by(Gender) |> summarize(q = quantile(Height, c(0, 0.25, 0.5, 0.75, 1))) # Error: `summarize()` must return a single value per group. # ✗ `q` is a vector of length 5. # ── ATTEMPT 2: reframe() — designed for multi-row returns ─────────────────── # reframe() lifts the one-row restriction: each group can produce # as many rows as the expression returns. heights |> group_by(Gender) |> reframe( pct = c(0, 25, 50, 75, 100), # label column (optional but useful) q = quantile(Height, c(0, .25, .5, .75, 1)) ) # # A tibble: 10 × 3 # Gender pct q # # 1 female 0 137. # 2 female 25 160. # 3 female 50 163. # 4 female 75 167. # 5 female 100 180. # 6 male 0 155. # 7 male 25 170. # 8 male 50 175. # 9 male 75 180. #10 male 100 200. # ── SIDE-BY-SIDE: what summarize() CAN do ─────────────────────────────────── # summarize() works fine when every expression returns exactly ONE value. # Use it for mean, median, sd, IQR, n(), etc. heights |> group_by(Gender) |> summarize( n = n(), mean = mean(Height) |> round(1), sd = sd(Height) |> round(1), median = median(Height) |> round(1), iqr = IQR(Height) |> round(1) ) # # A tibble: 2 × 6 # Gender n mean sd median iqr # # 1 female 2976 163. 7.2 163. 10.2 # 2 male 2759 176. 7.3 176. 10.3 # ── RULE OF THUMB ──────────────────────────────────────────────────────────── # summarize() → one row per group (scalar aggregates) # reframe() → any rows per group (vector-returning functions)