Syntopy in North American Passerines

Analysis of BBS Data with R

Syntopy
Species Coexistence
Spatial Data
Birds
R
BBS Data
Author

Matěj Tvarůžka

Published

March 10, 2026

NoteMaterials and Methods

The study will use data from the North American Breeding Bird Survey (BBS), a long-term, standardised monitoring programme that records bird assemblages across approximately 2,900 routes annually. Each route includes 50 point counts spaced at 0.5-mile intervals. I will analyse patterns of syntopy at two spatial resolutions:

  1. Point scale (individual stops) and

  2. Transect scale (combined stops along each route).

To infer drivers of syntopy, I will replicate the analytical framework of Remeš & Harmáčková (2023), which uses cooccurrence analyses and species trait data to identify ecological predictors of coexistence. A novel feature of this thesis will be analysing syntopy at two spatial resolutions (see above).

Remeš, V. and Harmáčková, L. (2023), Resource use divergence facilitates the evolution of secondary syntopy in a continental radiation of songbirds (Meliphagoidea): insights from unbiased co-occurrence analyses. Ecography, 2023: e06268. https://doi.org/10.1111/ecog.06268

1 Data Preparation

1.1 Sister Pairs Extraction

In this code I will select sister species pairs of North American passerines for the subsequent analysis of syntopy using these packages:

clootl, diverge, tidyverse and ape.

Firstly we are going to select the phylogeny of wood-warblers to try the workflow. We can get the acces to eBird taxonomy files using taxonomyGet(), than we select the family of wood-warblers (Parulidae).

taxonomy <- taxonomyGet(taxonomy_year = 2021)
warblers <- taxonomy |> 
  filter(FAMILY == "Parulidae (New World Warblers)")
head(warblers, 3)
TAXON_ORDER SPECIES_CODE TAXON_CONCEPT_ID PRIMARY_COM_NAME SCI_NAME ORDER1 FAMILY ott_id ott_name ott_tax_sources ott_match_type H_M_name H_M_match_type Birdlife_name Birdlife_match_type IOC_name IOC_match_type underscores
32843 ovenbi1 avibase-CEA5B6AA Ovenbird Seiurus aurocapilla Passeriformes Parulidae (New World Warblers) 285207 Seiurus aurocapilla ncbi:182946,worms:422653,gbif:2489590,irmng:11346310,irmng:11704550 canonical_match Seiurus aurocapilla concepts_match Seiurus aurocapilla concepts_match Seiurus aurocapilla concepts_match Seiurus_aurocapilla
32847 woewar1 avibase-295C4CD6 Worm-eating Warbler Helmitheros vermivorum Passeriformes Parulidae (New World Warblers) 860003 Helmitheros vermivorum ncbi:182932,worms:422651,gbif:2489603,irmng:11833136,irmng:10856823 canonical_match Helmitheros vermivorum concepts_match Helmitheros vermivorum concepts_match Helmitheros vermivorum concepts_match Helmitheros_vermivorum
32849 louwat avibase-7AB0F3A4 Louisiana Waterthrush Parkesia motacilla Passeriformes Parulidae (New World Warblers) 660355 Parkesia motacilla ncbi:231571,worms:567886,gbif:6093862,irmng:10452680,irmng:11797571 canonical_match Parkesia motacilla concepts_match Parkesia motacilla concepts_match Parkesia motacilla concepts_match Parkesia_motacilla

We need to select the species names vector for the tree extraction:

warb_names_vec <- warblers |> 
  select(SCI_NAME) |> 
  pull(SCI_NAME)
glimpse(warb_names_vec)
 chr [1:111] "Seiurus aurocapilla" "Helmitheros vermivorum" ...

We can extract the tree using extractTree() function from clootl package:

tree <- extractTree(species = warb_names_vec, taxonomy_year = 2021)
tree

Phylogenetic tree with 111 tips and 110 internal nodes.

Tip labels:
  Setophaga_chrysoparia, Setophaga_virens, Setophaga_occidentalis, Setophaga_townsendi, Setophaga_graciae, Setophaga_nigrescens, ...
Node labels:
  mrcaott5620ott285207, mrcaott5620ott860003, mrcaott5620ott285210, mrcaott5620ott85249, mrcaott5620ott63581, mrcaott5620ott757859, ...

Rooted; includes branch length(s).

We can plot it using ape package.

plot(tree, type = "fan", cex = 1.5, tip.color = "darkblue")

Now it’s time to extract species pairs using function extract_sisters() from diverge package:

sister_pairs <- extract_sisters(tree)
glimpse(sister_pairs)
Rows: 38
Columns: 2
$ sp1 <chr> "Setophaga_chrysoparia", "Setophaga_occidentalis", "Setophaga_grac…
$ sp2 <chr> "Setophaga_virens", "Setophaga_townsendi", "Setophaga_nigrescens",…