Lesson 5

A

Locked — confirm your name above to begin.

Two researchers, Peter and Rosemary Grant, went to a small island in the Galápagos called Daphne Major with their students. Every year from 1975 to 2012 they watched the small Geospiza "finches" on that small island, and captured every single one… every single year.

In the plot below is one of those measurements, the depth of the beak, for 943 birds all measured in a single field season. 787 of them are Geospiza fortis; 156 of them are Geospiza scandens. We are going to examine the difference between these two birds the same way we did for male and female body mass.

Find a value of beak depth that minimises your error for fortis. Then find an adjustment between fortis and scandens that minimises the error for scandens.

Does knowing what species of bird you are going to catch clearly improve your prediction of its beak depth?

  • 943 birds measured in one field season: 787 fortis, 156 scandens.
  • One box per species, on the beak depths as they were measured. The box holds the middle half of that species, the line inside it is the middle bird, the diamond is the average, and the whiskers reach the 5th and 95th.
  • Two sliders: a depth for a fortis, and an adjustment added only for a scandens. Each one draws as a rule across its own species' box.
  • The fortis number is carried down through the scandens box as a pale dashed line, so you can see what predicting one with the other's number costs.
  • Under the plot: that cost in millimetres, against what it costs with your adjustment.
average miss — fortis:   scandens:
a scandens predicted with your fortis number is off by:  |  with your adjustment:  |  so the species label is worth:
fortis scandens

Controls

9.00
0.00

To open Stage B

  • Bring both species' average miss to within 0.03 mm of zero. neither is there yet
Stage B is open.

R code

b <- read.csv("data/clean/finch_individuals.csv")b <- b[b$year == 1987, ]base <- 9.00adj  <- 0.00guess <- base + adj * (b$species == "scandens")tapply(b$beak_depth - guess, b$species, mean)# the panel you are looking atboxplot(beak_depth ~ species, data = b, horizontal = TRUE)abline(v = c(base, base + adj))# what the label is worth on a typical birdsc <- b$beak_depth[b$species == "scandens"]mean(abs(sc - base)); mean(abs(sc - (base + adj)))

B

Solve Stage A to unlock this section.

Part A showed the beak depth for hundreds of birds measured in one year, and we found clear evidence that knowing what species of bird it was improved our estimate of its beak depth. But the Grants didn't catch the birds in one year only! They caught every bird for their focal species on the island every year for 40 years!

So now we ask: does knowing what year a particular bird was caught clearly improve our prediction of beak depth if we also know its species?

We'll fit lines for both species over time separately, to see if the amount of beak-depth information knowing the year a bird was captured in is clearly different for the two species.

  • Across: year. Up: the average beak depth measured that year, 1973 to 2012.
  • Every dot is an average of hundreds of birds, not a bird. The bar through it is the Grants' published 95% interval on that year's average.
  • Under the plot: the average error for each species in the first half of the record and the second. All four on zero, and there is nothing systematic left for a straight line to pick up.
  • Under the plot: each species' trend per decade, and how far its line sits from the averages in a typical year.
  • The scandens sliders stay dark until fortis is fitted.
fortis average error — to 1992: after:
scandens average error — to 1992: after:
trend per decade — fortis:   scandens:  |  typical miss — fortis:   scandens:
fortis scandens

Controls

9.20
0.000
0.00
0.000

To open Stage C

  • Get your average error below 0.05 mm for each species, in the first half of the record and the second. fortis first
  • Answer both questions below.
Both lines are down and all four errors are on zero. Stage C is open.
Keep all four average errors on zero, and try it on the sliders before you answer.
1. Can you find a positive trend in fortis beaks over time while keeping the error low?
2. Can you find a positive trend in scandens beaks over time while keeping the error low?

R code

d <- read.csv("data/clean/finch_beak.csv")dec <- (d$year - 1973) / 10sc  <- d$species == "scandens"fbase <- 9.20frate <- 0.000sadj  <- 0.00sradj <- 0.000guess <- fbase + frate*dec + sc*(sadj + sradj*dec)tapply(d$beak_depth - guess, list(d$species, d$year > 1992), mean)# the same four numbers, found for youcoef(lm(beak_depth ~ dec * species, data = d))

C

Solve Stage B to unlock this section.

In Part B you can see that the trends between the two birds are quite different when you have forty years of data. Which means that if you know what year the Grants were on Daphne Major, you know — from the two lines you fitted in Part B — that you need to make a different prediction for the beak depth of an unobserved Geospiza scandens than you do for an unobserved Geospiza fortis.

Most studies do not last forty years and collate everything. So here we are going to pretend the data are different than they are: instead of getting a full forty, the Grants got some number of field seasons. And we are going to ask what the lines look like, and whether the range of plausible lines still separates the birds out when you have less data.

This is a way of determining how clear the difference is, and how quickly the difference could have been noticed.

  • Upper panel: only the seasons the current record actually drew. Four seasons means four points per species, not forty.
  • Each point is still an average of hundreds of birds, and the bar through it is still the 95% interval on that average.
  • Pale lines: the rate fitted to each of the last few records.
  • Under the plot: of all the records you have taken at this length, how many put each species' trend the right way up and how many put it upside down. Both species really fall, so every rising estimate is an error.
  • Changing the number of seasons starts the record over.
  • The two ranges of plausible rates turn green when they stop overlapping.
trend estimated
falling
trend estimated
rising
fortis
scandens
seasons per record: 10   records taken: 0  |  the two ranges of plausible rates:

Controls

10

To open Stage D

  • Get the two ranges of plausible rates apart, on at least 150 records at one setting. not yet
  • Answer the question below.
The two ranges of plausible rates no longer touch. Stage D is open.
Work back down the seasons slider. What is the shortest record that still pulls the two ranges of plausible rates apart?
field seasons

R code

d <- read.csv("data/clean/finch_beak.csv")k <- 10   # field seasons in each recordrate <- function(sp) {  y <- sample(unique(d$year), k, replace = TRUE)  s <- d[d$species == sp, ]  s <- s[match(y, s$year), ]  coef(lm(beak_depth ~ I((year - 1973)/10), data = s))[2]}cloud <- sapply(c("fortis", "scandens"),                 function(sp) replicate(500, rate(sp)))apply(cloud, 2, quantile, c(.025, .975))

D

Solve Stage C to unlock this section.

In Parts B and C you observed that the finches changed clearly over time — in the sense that if you know what year a bird was collected, you will be less wrong about its beak depth than if you don't know what year it was collected. You also found that if you know what species a bird from Daphne Major is, you will be less wrong about its beak depth than if you don't know what species it is.

Why does time, itself, improve our ability to predict beak depth? Time doesn't impact finch populations. Geospiza fortis captured in 2010 have smaller beaks than Geospiza fortis captured in 1985… but is that due to something, or just random change? Is there a driver of beak depth?

In addition to catching birds, the Grants also watched them and saw what the birds ate. They counted the types of seeds the birds ate, and classified them into categories based on seed size and hardness.

The Grants had an hypothesis: big beaks take big energy to grow, and big seeds take big beaks to break. So if there are lots of small seeds, every bird eats, but big-beaked birds burn more calories. If there are lots of big seeds, big-beaked birds eat, but small-beaked birds starve.

They tested that idea by looking at the beak depth of birds based on whether last year there were a lot of big, hard seeds or not. You can test that same idea now.

  • Across: the share of the seed crop that was big and hard, counted the year before.
  • Up: the average beak depth measured the following year. Sixteen years of overlap, 1976 to 1991.
  • Each slider is the whole shift: what a species' average beak depth does between a crop with none of it big and hard and a crop with all of it.
  • The height of each line is set for you — each one is pinned through its own species' averages — so the only thing you are choosing is the tilt.
  • Under the graph: what is left of each species' change per decade once the crop is in the fit.
average error, lean crops / rich crops — fortis: /   scandens: /
change per decade over these 16 years — with the crop left out:  |  with it in:
fortis scandens

Controls

0.00
0.00

To finish the lesson

  • Get your average error below 0.03 mm for each species, in lean crops and in rich crops alike. none of the four yet
  • Answer the question below.
For the same shift in the seed crop, how much further does the fortis population average shift than the scandens average? Use your own two numbers.
mm

R code

d <- read.csv("data/clean/finch_beak.csv")s <- read.csv("data/clean/finch_seeds.csv")s$year <- s$year + 1          # last year's crop, this year's birdsd <- merge(d, s, by = "year")fresp <- 0.00sresp <- 0.00# each tilt pinned through its own species' averagesfor (sp in c("fortis", "scandens")) {  k <- d$species == sp; r <- if (sp == "fortis") fresp else sresp  base <- mean(d$beak_depth[k]) - r * mean(d$large_share[k])  print(mean(d$beak_depth[k] - (base + r * d$large_share[k])))}# year, before and after the crop is allowed incoef(lm(beak_depth ~ I(year/10), data = d[d$species == "fortis", ]))coef(lm(beak_depth ~ I(year/10) + large_share, data = d[d$species == "fortis", ]))