Lesson 8 Applications
Now that we know how to extract and zero-fill data from eBird, let’s do something with these data! We’ll start by summarizing the data to show the trajectory of observation frequency over the course of the year. Next, we’ll make a basic presence-absence map of eBird observations. More advanced topics are covered in part II of this workshop, which focuses on using eBird data to model species distributions. We’ll start a new script for this lesson: 02_applications.R
.
8.1 Frequency trajectories
The genus Cardellina contains five New World warbler species, including some of the most spectacular birds in North America: Canada Warbler, Red Warbler, and Pink-headed Warbler. Let’s extract and zero-fill data for three of the species in this genus within Guatemala.
library(auk)
library(sf)
library(rnaturalearth)
library(lubridate)
library(tidyverse)
f_ebd <- "data/ebd_cardellina.txt"
f_sed <- "data/sed_cardellina.txt"
# extract
filters <- auk_ebd("ebd_2014-2015_yucatan.txt",
file_sampling = "ebd_sampling_2014-2015_yucatan.txt") %>%
auk_species(c("Canada Warbler", "Wilson's Warbler",
"Pink-headed Warbler")) %>%
auk_country("Guatemala") %>%
auk_complete() %>%
auk_filter(f_ebd, f_sed)
# zero-fill
cardellina_zf <- auk_zerofill(f_ebd, f_sed, collapse = TRUE)
count(cardellina_zf, scientific_name, species_observed)
#> # A tibble: 6 x 3
#> scientific_name species_observed n
#> <chr> <lgl> <int>
#> 1 Cardellina canadensis FALSE 6454
#> 2 Cardellina canadensis TRUE 54
#> 3 Cardellina pusilla FALSE 4795
#> 4 Cardellina pusilla TRUE 1713
#> 5 Cardellina versicolor FALSE 6322
#> 6 Cardellina versicolor TRUE 186
Next, let’s summarize these data, calculating the frequency of observation on eBird checklists by month.
cardellina_freq <- cardellina_zf %>%
mutate(month = month(observation_date)) %>%
group_by(scientific_name, month) %>%
summarize(obs_freq = mean(species_observed)) %>%
ungroup()
In preparation for plotting, we can add the common names of the species by joining in the ebird_taxonomy
data frame, which is included with auk
. In addition, we’ll convert the integer month numbers to dates–using the midpoint of each month–to aid axis labeling.
cardellina_comm <- cardellina_freq %>%
inner_join(ebird_taxonomy, by = "scientific_name") %>%
select(common_name, month, obs_freq) %>%
mutate(month_midpoint = ymd(str_glue("2019-{month}-15")))
Finally, let’s make a frequency trajectory for these four species.
ggplot(cardellina_comm) +
aes(x = month_midpoint, y = obs_freq, color = common_name) +
geom_point() +
geom_line() +
scale_x_date(date_breaks = "2 months",
date_labels = "%b") +
scale_color_brewer(palette = "Set1") +
labs(x = "Month", y = "Observation Frequency",
color = NULL) +
theme(legend.position = "bottom")
We have several different patterns going on here:
- Pink-headed Warblers is a resident species, present year-round at fairly low abundance
- Wilson’s Warbler spends the winter in Guatemala and is common during that period
- Canada Warbler appears to only pass through Guatemala during migration
8.2 Maps
Continuing with the same dataset, let’s make a presence-absence map for Pink-headed Warbler. We’ll start by filtering the zero-filled data to only Pink-headed Warbler observations and converting these points to a spatial format using the sf
package.
pihwar <- cardellina_zf %>%
filter(scientific_name == "Cardellina versicolor") %>%
st_as_sf(coords = c("longitude", "latitude"), crs = 4326)
Next, we’ll use rnaturalearth
to get some contextual GIS data to use in our maps. This is an amazing source for free GIS data for making maps.
ne_country <- ne_countries(continent = "North America", returnclass = "sf") %>%
st_geometry()
ne_gt <- ne_countries(country = "Guatemala", returnclass = "sf") %>%
st_geometry()
# restrict to points falling within Guatemala, removes those over water
pihwar <- pihwar[ne_gt, ]
Finally, we’ll make a presence-absence map, building it up in layers. There are lots excellent tools for mapping in R; however, here we’ll use the basic plot()
function from the sf
package. Other good options include ggplot2
and tmap
.
par(mar = c(0.25, 0.25, 0.25, 0.25))
# start by defining the bounds of the map with an empty plot
plot(ne_gt, col = NA, border = NA)
# borders
plot(ne_country, col = "grey80", border = "white", add = TRUE)
plot(ne_gt, col = "grey70", border = "white", add = TRUE)
# not observed
pihwar_abs <- filter(pihwar, !species_observed) %>%
st_geometry()
plot(pihwar_abs, col = alpha("grey20", 0.3), pch = 19, cex = 0.25, add = TRUE)
# present
pihwar_pres <- filter(pihwar, species_observed) %>%
st_geometry()
plot(pihwar_pres, col = alpha("orange", 1), pch = 19, cex = 0.5, add = TRUE)
title("Pink-headed Warbler eBird Observations", line = -1)
legend("bottomright",
col = c("grey20", "orange"),
legend = c("Not reported", "Present"),
pch = 19)
box()
Based on this map, we see that Pink-headed Warbler is restricted to the southwestern highlands of Guatemala.
Exercise
Make a similar map of Wilson’s Warbler (Cardellina pusilla) observations.
# prepare data
wilwar <- cardellina_zf %>%
filter(scientific_name == "Cardellina pusilla") %>%
mutate(pres_abs = if_else(species_observed, "Present", "Not detected")) %>%
st_as_sf(coords = c("longitude", "latitude"), crs = 4326)
wilwar <- wilwar[ne_gt, ]
# make map
par(mar = c(0.25, 0.25, 0.25, 0.25))
plot(ne_gt, col = NA, border = NA)
plot(ne_country, col = "grey80", border = "white", add = TRUE)
plot(ne_gt, col = "grey70", border = "white", add = TRUE)
# not observed
wilwar_abs <- filter(wilwar, !species_observed) %>%
st_geometry()
plot(wilwar_abs, col = alpha("grey20", 0.3), pch = 19, cex = 0.25, add = TRUE)
# present
wilwar_pres <- filter(wilwar, species_observed) %>%
st_geometry()
plot(wilwar_pres, col = alpha("orange", 1), pch = 19, cex = 0.5, add = TRUE)
title("Wilson's Warbler eBird Observations", line = -1)
legend("bottomright",
col = c("grey20", "orange"),
legend = c("Not reported", "Present"),
pch = 19)
box()