Goals
The goal of this exploratory data analysis (EDA) is to investigate the effects of roads and traffic (i.e. varying traffic levels and varying distances to roads) on mammal species richness and species-specific occurrence at an urban-wildland interface, using camera trap data. These are the following tasks we will complete with this EDA:
Determine how many days, on average, cameras were active across the study area.
Determine how many different species were detected across all camera traps.
Create one final, cleaned dataframe for all independent species detections across the study area.
Determine which species were detected the most across the study area.
Determine if species richness differs in relation to treatment area (permanently closed roads, temporarily closed roads, and permanently open roads) and distance to roads (100 m vs. 500 m from any road).
Determine if occurrence of traffic-tolerant species, i.e., raccoon (Procyon lotor), white-tailed deer (Odocoileus virginianus), and coyote (Canis latrans), and traffic-sensitive species, i.e., black bear (Ursus americanus) and fisher (Pekania pennanti), differs between treatment area (permanently closed roads, temporarily closed roads, and permanently open roads) and distance to roads (100 m vs. 500 m from any road).
Determine if there are any correlations between species co-occurrence across the study area.
Background
Road networks and motorized vehicle traffic pose a significant threat to wildlife and contribute to worldwide biodiversity loss (Benitez-Lopez, Alkemade, and Verweij 2010). Roads and traffic threaten the long-term viability of mammal populations by reducing landscape connectivity and access to resources, increasing direct mortality through animal-vehicle collisions, and reducing habitat quality, e.g. through noise disturbance, pollution, and so on (Fahrig and Rytwinski 2009). Traffic can be especially problematic at the urban-wildland interface, where developed landscapes meet natural spaces and where roads intersect areas with high animal densities. However, responses to traffic (and the removal of traffic) vary across species and context. To explore the effects of traffic reduction on the mammal community in Gatineau Park, Québec, Canada, which has implemented temporal road closures throughout the park for conservation purposes, we deployed 30 infrared motion-activated camera traps at varying distances from roads (100 m vs. 500 m) across three treatment areas: roads permanently closed to motorized vehicle traffic, roads temporarily closed to traffic (closed four days per week and every night of the week), and permanently open roads, from May through August of 2023.
Description of Data and Data Structure
Each camera was programmed to take a single image whenever motion and/or body heat was detected in front of the camera’s field of view. Each camera was also programmed to take a single image everyday at noon to ensure camera operability. All raw image data (collected using 30 camera traps across 30 sites) were manually transcribed using TimeLapse Image Analyzer (Greenberg, Godin, and Whittington 2019), wherein all species within all images were identified. Once all images were transcribed for a single camera, a CSV file was produced with all species detection information. This information is stored as columns within each CSV file (e.g. Site, DateTime, Species, Age, Sex, etc.). There are also 2 predictor variable columns, Treatment and Distance. Treatment corresponds to three different treatment areas (Close = areas where roads are permanently closed to motorized vehicle traffic; Mit = areas where roads are temporarily closed to vehicle traffic four days a week and every night of the week; and Open = areas where roads are permanently open). The Distance column contains either a “C” for close (100 m from any road) or an “F” for far (500 m from any road). Each CSV file has a total of 39 columns, and each row corresponds to an individual image (e.g. if a camera trap from site 01-100 captured 500 images over the course of the 4-month deployment, there should be 500 rows in the 01-100 CSV file). Although there were only 30 camera sites, there are 41 CSV files for 2023 that will be used in this EDA, because some sites had multiple deployments (wherein a camera had to be taken down and replaced with another camera). All 41 CSV files can be found in the Input folder for this EDA.
Required Packages
The following packages are required for this EDA.
library(tidyverse)
library(rmarkdown)
library(reproducible)
library(gridExtra)
library(corrplot)View the Data
Let’s take a look at the data we will be working with. Navigate through the table below to check out all 39 columns and the first 20 rows of the dataframe.
Table 1. Untidy dataframe being used for this EDA, containing all merged CSV files of camera trap image data for 2023, collected in Gatineau Park, Québec, Canada.
How many rows are in the dataframe?
nrow(all_image_df) [1] 30378
Corresponding to 30,378 images!
Data Hygiene
We will start with some initial data checks and tidying.
First, we will check that the Site column includes all 30 sites (from 01-100 to 15-500), the Treatment column includes three possible treatments, and the Distance column includes two possible distances.
unique(all_image_df$Site) [1] "01-100" "01-500" "02-100" "02-500" "03-100" "03-500" "04-100" "04-500"
[9] "05-100" "05-500" "06-100" "06-500" "07-100" "07-500" "08-100" "08-500"
[17] "09-100" "09-500" "10-100" "10-500" "11-100" "11-500" "12-100" "12-500"
[25] "13-100" "13-500" "14-100" "14-500" "15-100" "15-500"
unique(all_image_df$Treatment) [1] "Mit" "Open" "Close"
unique(all_image_df$Distance) [1] "C" "FALSE"
We can see that the Distance column is reading “F” (for far or 500 m) as FALSE. Let’s rename the two possible entries in this column to something more meaningful: 100 or 500.
all_image_df <- all_image_df %>%
mutate(Distance = case_when(
Distance == "C" ~ "100",
Distance == "FALSE" ~ "500"))
unique(all_image_df$Distance) [1] "100" "500"
Finally, we will make Site, Treatment, and Distance into factors, and make sure our DateTime column is being read as date and time data. Click on “Code” below to see how to do this.
Code
all_image_df$Site <- as.factor(all_image_df$Site)
all_image_df$Treatment <- as.factor(all_image_df$Treatment)
all_image_df$Distance <- as.factor(all_image_df$Distance)
all_image_df <- all_image_df %>%
mutate(DateTime = as_datetime(DateTime)) Task 1: How many days, on average, were cameras active across the study area?
Now that our date and time values are fixed, let’s ask our first question: How many days were cameras active, on average, across the study area?
all_image_df %>%
group_by(Site) %>%
summarise(deploy = min(DateTime),
retrieve = max(DateTime),
range = difftime(retrieve, deploy, units = "days")) %>%
summarize(mean = mean(range),
sd = sd(range))# A tibble: 1 × 2
mean sd
<drtn> <dbl>
1 80.23322 days 18.6
Each camera was active across the study area for an average of 80.23 ± 18.6 days.
Task 2: How many different species were detected across all cameras?
n_distinct(all_image_df$Species) gives us 27 distinct entries for our Species column, so presumably there are 27 unique species, right? However…
Code
unique(all_image_df$Species) [1] "Staff" NA "White-tailed deer"
[4] "Black bear" "Grey squirrel" "Unknown"
[7] "Raccoon" "Coyote" "Raven"
[10] "Fisher" "Common grackle" "Red-breasted nuthatch"
[13] "Wild turkey" "Human" "Moose"
[16] "Canada goose" "Porcupine" "American robin"
[19] "Woodchuck" "Red squirrel" "Long-tailed weasel"
[22] "Red fox" "Barred owl" "American mink"
[25] "Unknown mustelid" "Other birds" "Striped skunk"
…when we take a closer look, we can see that there are NA’s and some entries we are not interested in (e.g. Human/Staff, unknowns, etc.). So let’s remove all entries we are not interested in, and see how many species are left.
Code
all_image_df <- all_image_df %>%
filter(!(is.na(Species)) & !(Species == "")) %>%
filter(!(Species == "Staff") & !(Species == "Human")
& !(Species == "Other birds")
& !(Species == "Unknown mustelid")
& !(Species == "Unknown"))
n_distinct(all_image_df$Species)[1] 21
There are 21 unique, known species detected across the study area.
Data Transformation and Wrangling
Now it’s time to finish creating our final dataframe. To do this, we need to calculate independent detections, which are defined as species detections that are at least 30 minutes apart. This is integral to working with camera trap data. For example, if a red fox is detected on a camera at 10:00am, and then another red fox is detected at the same camera at 10:05am, it is very likely the same individual. Thus, 30 minutes is a common interval used to denote independence between individual images of the same species (Burton et al. 2015).
First, let’s select the columns we want to work with and save this as a new dataframe. Then we will add an additional column specifying time difference between each image (timediff).
final_df <- all_image_df %>%
select(Site, Species, Total, DateTime, Event, Treatment, Distance)
final_df <- final_df %>%
arrange(Site, Species, Total, DateTime, Event, Treatment, Distance) %>%
group_by(Site, Species) %>%
mutate(timediff = as.numeric(difftime(DateTime,lag(DateTime),
units = "mins")))Next, we will use for-loops to assign an event ID to each image based on our 30-minute window, which will be added as a new column, Event.ID.
Code
mins <- 30
final_df$Event.ID <- 9999
seq <- as.numeric(paste0(nrow(final_df),0))
seq <- round(seq,-(nchar(seq)))
for (i in 2:nrow(final_df)) {
final_df$Event.ID[i-1] <- paste0("E",format(seq, scientific = F))
if(is.na(final_df$timediff[i]) | abs(final_df$timediff[i]) > (mins)){
seq <- seq + 1
}
}
if(final_df$timediff[nrow(final_df)] < (mins)|
is.na(final_df$timediff[nrow(final_df)])){
final_df$Event.ID[nrow(final_df)] <- final_df$Event.ID[nrow(final_df)-1]
} else{final_df$Event.ID[nrow(final_df)] <- paste0("E",format(seq+1, scientific = F))
}And then we will only keep the first row for each independent event in our dataframe, which excludes all images of the same species within 30 minutes of each other.
final_df <- final_df %>%
group_by(Event.ID) %>%
slice(1)Our dataframe should be a lot smaller now! How many rows do we have left?
[1] 1228
Finally, let’s determine species richness per site and add this as a new column to our dataframe.
Code
final_df <- final_df %>%
group_by(Site) %>%
mutate(Richness = (length(unique(Species))))Task 3: Create a final, tidy dataframe
Now we can check out our final dataframe made up of independent species detections: final_df. We now have a total of 10 columns of interest and 1,228 rows, corresponding to 1,228 independent species detections. The final dataframe (saved as a CSV file) can be found in the Output folder of this EDA.
Table 2. Final, tidy dataframe being used for this EDA, containing indepedent detection data for all detected species across 30 camera traps collected in 2023 in Gatineau Park, Québec, Canada.
Data Visualization
Now we can explore our data in more detail with some graphical visualizations.
Task 4: Which species were detected the most across all cameras?
Let’s take a look at the number of independent detections across all species captured on the cameras. Based on the figure below, we can see that raccoon were the most commonly detected species (with 520 independent detections), followed by white-tailed deer (487 detections), and black bear (68 detections).
Task 5: Does species richness differ across treatment areas and distance to roads?
Let’s take a look at species richness in relation to treatment area (varying levels of traffic) and distance (varying distances to the road).
We can see that mean species richness is highest in closed and open treatment areas (pretty similar).
We can see that mean species richness is highest closer to roads (100 m).
Task 6: Does species-specific occurrence differ across treatment areas and distance to roads?
Let’s take a look at species-specific occurrence in relation to treatment area and distance to roads. We are interested in exploring the occurrence of traffic-tolerant species, such as raccoon, white-tailed deer, and coyote, compared to traffic-sensitive species, such as black bear and fisher.
Based on the following figures, we can see that raccoon and coyotes were everywhere, especially in areas with more traffic (Open treatment), however, coyote tended to be detected further from roads, compared to raccoon. White-tailed deer were mostly detected in the mitigation treatment area, at sites closer to roads.
Based on the following figures, we can see that black bears were more often detected in the mitigation treatment area and closed treatment area, compared to the open treatment area, and were often detected closer to roads. Fisher were also primarily detected in the mitigation area, but at sites further from the road. However, there were not a lot of independent detections for fisher, with no detections in the closed treatment area.
Task 7: Are there any correlations between species co-occurrence across the study area?
Finally, let’s take a look at species co-occurrence correlations of our most commonly occurring species.
Based on the following figure, we can see that there were no significant correlations between species (no values > 0.7). However, we can see a weak positive correlation between coyote and raccoon (0.53) and grey squirrel and red fox (0.4), and a weak negative correlation between white-tailed deer and fisher (-0.34).
Conclusions
Based on this preliminary exploratory data analysis using camera trap data, we can see that, in general, average species richness tends to be highest in areas with more traffic and at sites closer to roads. This may be due to the presence of many urban and traffic-tolerant species in the study area. However, areas with less traffic (mitigation and closed treatment areas) tend to have higher species occurrences of traffic-sensitive species, such as black bear and fisher. An interesting observation, however, is that species occurrence in the mitigation treatment area tends to be consistently higher at sites closer to roads for many species, which may indicate increased roadside use (e.g. for foraging, ease of travel on linear features, etc.) as traffic is reduced. Thus, we may be seeing greater overall mammal presence in roadside habitats due to traffic reduction.
References