New data cleaning/preperation functions for the Diel.Niche R package
At the start of 2024 Brian Gerber, Kadambari Devarajan, Zach Farris and I released the Diel.Niche
R package and companion paper in the Journal of Animal Ecology. In this R package, we provide a way to quantify a species diel phenotype (e.g., nocturnal, diurnal, crepuscular, and cathemeral) with date time observations collected on a species (e.g., photo records from camera traps). What we did not do, however, was make it easy for users to prepare their data to be analyzed within Diel.Niche
, and so we finally got around to fixing this!
This week we just released the next version of Diel.Niche
, and with it comes a suite of functions to make it
easier than ever to get your data prepared for an analysis. These functions include:
-
trim.time()
: This function filters detection records so that observations within a specified number of minutes from the previous observation (at the same site) are removed. For multi-species datasets, records should be thinned by site and species detected at that site. This function can be used to thin, for example, camera trap or acoustic data where multiple detections in rapid succession may not be independent. -
make.diel.bin.list()
: This function generates a named list of logical expressions that define diel periods (e.g., day, night, and twilight) based on sunlight transition times computed from a given location, date, and time zone. It can either use default definitions or allow the user to define their own logical expressions. It validates those expressions against known solar event names, checks for logical consistency, and optionally visualizes the resulting diel bins. -
bin.diel.times()
: This function assigns datetime observations to diel bins (e.g., day, night, and twilight) based on sun angle transitions calculated with ‘suncalc::getSunlightTimes()’. The function uses user-defined logical expressions stored in a ‘diel.bin.list’ to classify times, and requires date time data as well as the spatial coordinates of the observation in decimal degrees.
To show how a full analysis would work, we have also provided an additional camera trapping dataset, camera.data
, which includes almost 2500 Virginia opossum (Didelphis virginiana) observations collected with camera traps throughout Chicago, Illinois, USA. If you have any ideas about new features or other kinds of enhancements for Diel.Niche
, feel free to request those on our issues page here.
# load packages
library(Diel.Niche)
library(dplyr)
library(tidyr)
# load in the example data, see
# help file for metadata (i.e., ?camera.data)
data(camera.data)
# thin the data by removing images of the same species
# at the same site that are within 15 minutes of
# one another. This is done with the new
# function Diel.Niche::trim.time().
thinned_data <- Diel.Niche::trim.time(
data = camera.data,
datetime.column = "datetime",
site.column = "surveyID",
species.column = "species",
minutes.between = 15,
progress.bar = TRUE
)
# This new function defines the diel
# bins (e.g., twilight, daym and night)
# to use for the analysis based
# on solar transitions that can be
# queried via suncalc::getSunlightTimes()
bin_list <- Diel.Niche::make.diel.bin.list()
# Determine the diel bin for each
# camera trap photo with the new
# fucntion Diel.Niche::bin.diel.times().
# This adds a new column 'dielBin' to
# the data.frame that categorizes the
# diel period (i.e., bin) associated
# to a date.time record.
thinned_data <- Diel.Niche::bin.diel.times(
data = thinned_data,
datetime.column = "datetime",
lat.column = "lat",
lon.column = "lon",
bin.type.list = bin_list,
na_vals = "remove"
)
# For this example, we are going to analyze
# the diel phenotype of opossum in the fall.
# The surveyID column has seasonal information
# and so we can determine fall data with that.
fall <- thinned_data[
grep("FA12", thinned_data$surveyID),
]
# generate counts of the three different dielBins.
y <- fall %>%
dplyr::count(
species, dielBin
) %>%
tidyr::pivot_wider(
names_from = dielBin,
values_from = n,
values_fill = 0 # fill missing dielBin values with 0
) %>%
data.frame
# convert the count columns to their own matrix,
# which is required by Diel.Niche::diel.fit().
for_diel.fit <- as.matrix(
y[,c("twilight", "day","night")]
)
# fit the model. Note that the order
# must be twilight, day, night!
output <- Diel.Niche::diel.fit(
y = for_diel.fit,
hyp.set = hyp.sets("Traditional"),
post.fit = TRUE
)
# The most supported model is: Nocturnal (Traditional).
# Now can visualize the posterior on a ternary graph.
Diel.Niche::triplot(
output
)