Skip to content

traitecoevo/birdnetprocess

Repository files navigation

birdnetprocess

Will Cornwell 2026-02-18

birdnetprocess

R-CMD-check test-coverage

birdnetprocess helps you process and visualize BirdNET detection results which can be overwhelming in their volume.

Install

# install.packages("devtools") # if needed
devtools::install_github("traitecoevo/birdnetprocess")
#> Using GitHub PAT from the git credential store.
#> Skipping install of 'birdnetprocess' from a github remote, the SHA1 (d6828172) has not changed since last install.
#>   Use `force = TRUE` to force installation

Data Requirements

BirdNET produces one output file per audio recording. The package supports both common output formats:

  • Raven selection tables (.txt, tab-delimited) — must contain Begin Time (s)
  • BirdNET Analyzer CSV output (.csv, comma-separated) — must contain Start (s) or Begin Time (s)

For automatic time processing, filenames must contain a timestamp in YYYYMMDD_HHMMSS format (e.g., SL21_20260118_112124.BirdNET.results.csv).


Use Case 1: Single Site Analysis

This is the most common scenario — you have one recorder deployed at one location and a folder of BirdNET output files. In this example the folder is detections_SL21/ containing ~46 CSV result files.

Step 1: Read the data

Use read_birdnet_folder() to read all BirdNET files in a single folder and combine them into one tibble:

library(birdnetprocess)
library(dplyr)

data <- read_birdnet_folder("detections_SL21")

When to use recursive? By default recursive = FALSE, which reads only the files directly in that folder. This is correct for standard BirdNET output which is flat. Set recursive = TRUE only if your results are split into sub-directories within the site folder.

Step 2: Quick summary

Get a snapshot of the dataset with summarise_detections():

summarise_detections(data, confidence = 0.7)
# # A tibble: 7 × 2
#   statistic                   value
#   <chr>                       <chr>
# 1 Number of species           49
# 2 Number of recordings        8042
# 3 Recording window            18 Jan 26 - 19 Jan 26
# 4 Most common species           Black Field Cricket
# 5 Peak hour                   2026-01-19 04:21:02
# 6 Average detections per day  4021
# 7 Average detections per hour 178.7111

Step 3: Visualise

Species counts — a quick bar chart of how many detections per species:

plot_species_counts(data, confidence = 0.5)

Top 10 Calls

Top 10 Calls

Activity trends with day/night shading — requires latitude, longitude, and timezone for the suncalc shading:

plot_top_species(
  data,
  n_top_species = 10,
  confidence = 0.6,
  latitude = -32.44,
  longitude = 152.24,
  tz = "Australia/Sydney"
)

Day Night Patterns

Day Night Patterns

Custom time binning — by default trends are plotted hourly. Use the unit parameter for finer resolution (any interval lubridate supports, e.g., "10 min", "30 min", "3 hours"):

plot_top_species(
  data,
  n_top_species = 5,
  confidence = 0.5,
  unit = "10 min"
)

10-Minute Trends

10-Minute Trends

Use Case 2: Multi-Site Project

When you have multiple recorders deployed across different locations, BirdNET typically outputs results into separate folders — one per site. In this example we have four site folders: detections_SL21/, detections_SL25/, detections_SL42/, and detections_SL_swamp/.

Step 1: Identify site folders

You can hard-code the paths or discover them automatically:

library(birdnetprocess)
library(dplyr)

# Option A: Hard-code folder paths
folders <- c(
  "detections_SL21", "detections_SL25",
  "detections_SL42", "detections_SL_swamp"
)

# Option B: Auto-discover folders matching a pattern
all_dirs <- list.dirs(".", full.names = FALSE, recursive = FALSE)
folders <- all_dirs[grepl("^detections_", all_dirs)]

Step 2: Read all sites

Use read_birdnet_sites() — it calls read_birdnet_folder() for each path and adds a Site column derived from the folder name:

all_data <- read_birdnet_sites(folders)

# Check the Site column
unique(all_data$Site)
# [1] "detections_SL21"    "detections_SL25"
# [3] "detections_SL42"    "detections_SL_swamp"

Step 3: Compare across sites

Use facet_by = "Site" in plot_top_species() to get side-by-side panels — one per site:

plot_top_species(
  all_data,
  n_top_species = 5,
  confidence = 0.5,
  facet_by = "Site",
  latitude = -32.44,
  longitude = 152.24,
  tz = "Australia/Sydney"
)

This produces a faceted plot with each site in its own panel, making it easy to compare species activity across locations.


Quick Reference: Which function should I use?

Scenario Function recursive Adds Site?
One folder of BirdNET results read_birdnet_folder() FALSE (default) No
One folder with sub-directories inside read_birdnet_folder() TRUE No
Multiple site folders for comparison read_birdnet_sites() FALSE (default) Yes

Rule of thumb:

  • If you’re working with one site, use read_birdnet_folder().
  • If you’re comparing sites, use read_birdnet_sites() — it gives you the Site column you need for facet_by = "Site" in plotting functions.

Dependencies

Dependencies (lubridate and ggplot2 are key) should be installed automatically when installing birdnetprocess from GitHub.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages