library(tidyverse)
library(palmerpenguins)Day 10 Activity: Summarizing the penguins
Monday, June 1, 2026
Setup
Today’s activity uses the penguins dataset (palmerpenguins package). Glimpse it before you start:
glimpse(penguins)Rows: 344
Columns: 8
$ species <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
$ island <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
$ bill_length_mm <dbl> 39.1, 39.5, 40.3, NA, 36.7, 39.3, 38.9, 39.2, 34.1, …
$ bill_depth_mm <dbl> 18.7, 17.4, 18.0, NA, 19.3, 20.6, 17.8, 19.6, 18.1, …
$ flipper_length_mm <int> 181, 186, 195, NA, 193, 190, 181, 195, 193, 190, 186…
$ body_mass_g <int> 3750, 3800, 3250, NA, 3450, 3650, 3625, 4675, 3475, …
$ sex <fct> male, female, female, NA, female, male, female, male…
$ year <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…
We will practice using two data verbs, summarize() and group_by(), as well as reduction functions like n() and mean().
Part 1
For each operation below, say which family it belongs to: reduction (variable to one number), transformation (variable to one value per row), or neither (a whole-table data verb).
| # | Operation | Family |
|---|---|---|
| 1 | The largest body mass in the dataset | [Your answer.] |
| 2 | Body mass converted from grams to kilograms | [Your answer.] |
| 3 | The number of penguins | [Your answer.] |
| 4 | Whether each penguin weighs more than 4000 g | [Your answer.] |
| 5 | The number of distinct islands | [Your answer.] |
| 6 | Labeling each penguin "heavy" or "light" |
[Your answer.] |
| 7 | Keeping only the Gentoo penguins | [Your answer.] |
| 8 | The standard deviation of flipper length | [Your answer.] |
The fastest test: does it return one number (reduction), one per row (transformation), or a whole new table (neither, that’s a data verb)? Number 7 is tricky.
Part 2
2a. Write a single summarize() that returns the number of penguins, the mean body mass, and the mean flipper length.
# Your code:2b. Run this, then explain in one sentence why the result is what it is:
penguins |>
summarize(avg_mass = mean(body_mass_g))# A tibble: 1 × 1
avg_mass
<dbl>
1 NA
[Your explanation here.]
2c. Fix 2b so it returns a real number. What one change did you make, and why does it work?
# Your fixed code:[Your explanation here.]
Part 3
For 3a–3d, first write down your prediction for how many rows the result will have and which columns it will contain. Then run it and check.
3a.
penguins |>
group_by(species) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE))Prediction (rows / columns): [Your answer.]
Actual: [Your answer.]
3b.
penguins |>
group_by(species, sex) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE),
.groups = "drop")Prediction (rows / columns): [Your answer.]
Actual: [Your answer.]
Did anything about the number of rows surprise you? (Look closely at the sex column.)
[Your answer.]
3c. This one is a trap. Predict before you run it, then run it:
penguins |>
group_by(body_mass_g) |>
summarize(n = n(), .groups = "drop")Prediction (rows / columns): [Your answer.]
Actual: [Your answer.]
What went wrong, and what does it tell you about which kinds of variables you should group by?
[Your answer.]
3d. Without grouping at all:
penguins |>
summarize(n = n())Prediction (rows / columns): [Your answer.]
Actual: [Your answer.]
Explain the relationship between 3a, 3b, and 3d in terms of “what does one row of the output represent?”
[Your answer.]
Part 4 — Don’t trust a mean without its n()
Run the finest grouping we can make from these three variables:
penguins |>
group_by(species, island, sex) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE),
.groups = "drop")4a. Which group has the fewest penguins? Would you be comfortable quoting that group’s avg_mass in a report? Why or why not?
[Your answer.]
4b. In one or two sentences: why is n = n() worth adding to every group summary you write, even when nobody asked for a count?
[Your answer.]
Code appendix
library(tidyverse)
library(palmerpenguins)
glimpse(penguins)
# Your code:
penguins |>
summarize(avg_mass = mean(body_mass_g))
# Your fixed code:
penguins |>
group_by(species) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE))
penguins |>
group_by(species, sex) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE),
.groups = "drop")
penguins |>
group_by(body_mass_g) |>
summarize(n = n(), .groups = "drop")
penguins |>
summarize(n = n())
penguins |>
group_by(species, island, sex) |>
summarize(n = n(), avg_mass = mean(body_mass_g, na.rm = TRUE),
.groups = "drop")