library(readr)
library(lubridate)
library(dplyr)
library(knitr)
library(kableExtra)
deployment <- read_csv("deployments.csv",
col_types = cols(start_date = col_character()))
#check the format of the start_date and end_date, if they are not like in this example: 2021-10-22 21:03:18 then you will have to modify it accordingly:
# Convert start_date from DD/MM/YYYY HH:MM to POSIXct
deployment$start_date <- dmy_hm(deployment$start_date) # Use dmy_hm for this specific format
deployment$end_date <- dmy_hm(deployment$end_date)
# Format start_date to the desired format YYYY-MM-DD HH:MM:SS
deployment$start_date <- format(deployment$start_date, "%Y-%m-%d %H:%M:%S")
deployment$end_date <- format(deployment$end_date, "%Y-%m-%d %H:%M:%S")
camtraps <- read.csv("images_LGDs.csv",
header = TRUE,
sep = ",",
stringsAsFactors = FALSE)
# this dataset has already been uploaded with timetamp %Y-%m-%d %H:%M:%SData Preparation - Occupancy Analysis (single species and season) - Sheep
Data Preparation
We have been using the datasets produced by Wildlife Insights after identifying the content of the photographs and filtering out those with humans.
In previous sessions, we have used a dataset based on the camera trapping data of Dr Bethany Smith, a former NTU PhD candidate. We mainly dealt with two datasets containing deployment data and raw image data.
The deployment dataset contains details of the camera trap location (longitude and latitude), the period of deployment and on which feature was placed (e.g. road, trail game).
The camera traps raw data contains details related to the the deployment ID, date and time of capture and the animal captured.
However, we need to create new data structures to use modelling techniques such as occupancy modelling and capture-recapture.
Initial preparatory steps
Import datasets and standardise the date and time for further analyses
Add site-specific covariates to the deployment data
Currently, we only have a covariate to describe where the camera was placed (feature_type). We can add other variables, for example elevation. You can use the elevatr package to retrieve elevation data based on geographical coordinates.
# install package if required
#install.packages("elevatr")
# Load necessary library
library(elevatr)
# Assuming deployment dataset contains 'longitude' and 'latitude' columns
coordinates <- data.frame(x = deployment$longitude, y = deployment$latitude)
# Get elevation data
elevation_data <- get_elev_point(coordinates, prj = "EPSG:4326", src = "aws")
# Add the elevation (in meters) as a new column to the deployment dataset
deployment$elevation <- elevation_data$elevationWe can also add another variable to give us an indication of how rugged the area where the camera was placed. We can calculate the Topographic Position Index (TPI), which compares the elevation of a point to the average elevation of nearby points:
Positive TPI: The location is higher than its surroundings (ridge).
Negative TPI: The location is lower than its surroundings (valley).
The following code will calculate this. I have just left the code here in case it becomes useful for you in the future!
# install packages if needed
#install.packages("raster","sp", "gstat")
# Load necessary libraries
library(elevatr)
library(raster)
library(sp)
library(gstat)
# Step 1: Get elevation data (same as the previous code)
coordinates <- data.frame(x = deployment$longitude, y = deployment$latitude)
# Extract elevation data using elevatr
elevation_data <- get_elev_point(coordinates, prj = "EPSG:4326", src = "aws")
# Step 2: Create a SpatialPointsDataFrame from the coordinates and elevation
coordinates_spdf <- SpatialPointsDataFrame(
coords = coordinates,
data = data.frame(elevation = elevation_data$elevation),
proj4string = CRS("+proj=longlat +datum=WGS84")
)
# Step 3: Define a finer grid for interpolation to avoid gaps (adjust resolution)
grid_extent <- extent(coordinates_spdf)
grid <- expand.grid(
x = seq(from = grid_extent@xmin, to = grid_extent@xmax, by = 0.005), # Finer resolution
y = seq(from = grid_extent@ymin, to = grid_extent@ymax, by = 0.005)
)
coordinates_grid <- SpatialPoints(grid, proj4string = CRS("+proj=longlat +datum=WGS84"))
# Step 4: Perform kriging interpolation with more nearby points (nmax = 100)
kriging_model <- gstat(formula = elevation ~ 1, locations = coordinates_spdf, nmax = 100)
elevation_kriged <- predict(kriging_model, newdata = coordinates_grid)[inverse distance weighted interpolation]
# Step 5: Convert the kriged result into a raster
elevation_raster <- rasterFromXYZ(as.data.frame(elevation_kriged)[, c("x", "y", "var1.pred")])
# Step 6: Calculate ruggedness using terrain function with 'tpi'
ruggedness <- terrain(elevation_raster, opt = "tpi", unit = "degrees")
# Step 7: Handle NA values: Replace NA or interpolate missing values
ruggedness[is.na(ruggedness[])] <- 0 # Option 1: Replace NA with 0 (flat terrain)
# Alternatively, use focal interpolation for missing values
ruggedness_filled <- focal(ruggedness, w = matrix(1, 3, 3), fun = mean, na.rm = TRUE, pad = TRUE)
# Step 8: Extract ruggedness values for each point
deployment$ruggedness <- extract(ruggedness_filled, coordinates_spdf)
# Replace NAs with median ruggedness
median_ruggedness <- median(deployment$ruggedness, na.rm = TRUE)
deployment$ruggedness[is.na(deployment$ruggedness)] <- median_ruggednessNow you can simplify the deployment dataset to show the data of interest, which will contain deployment data, but also the values for three covariates.
feature_type: is a covariate that could affect both the detection probability and also occupancy
elevation: is a covariate that could affect occupancy
ruggedness: is a covariate that could affect occupancy
library(dplyr)
# Create a new dataset with the specified columns
deployment_subset <- deployment[, c("deployment_id",
"longitude",
"latitude",
"start_date",
"end_date",
"feature_type",
"elevation",
"ruggedness")]
# Get the first 10 rows
first_10_rows <- head(deployment_subset, 10)
# Create a nice table
kable(first_10_rows, format = "html", caption = "Deployment Data with 3 covariates") %>%
kable_styling(full_width = FALSE, position = "left")| deployment_id | longitude | latitude | start_date | end_date | feature_type | elevation | ruggedness |
|---|---|---|---|---|---|---|---|
| D1_AA10-1 | 24.00188 | 45.62046 | 2021-07-20 09:53:00 | 2021-08-09 06:43:00 | Trail game | 1137 | -4.155159 |
| D1_AA11-1 | 23.98999 | 45.60232 | 2021-07-20 17:37:00 | 2021-08-10 18:57:00 | Road dirt | 1073 | -16.522067 |
| D1_AA12-1 | 24.00164 | 45.58462 | 2021-08-04 13:05:00 | 2021-09-21 09:11:00 | Road dirt | 1155 | -9.000408 |
| D1_AA12-2 | 24.00787 | 45.57602 | 2022-02-10 16:43:00 | 2022-03-30 12:47:00 | Road dirt | 1158 | -18.749835 |
| D1_AA13-2 | 23.98795 | 45.55146 | 2021-09-21 12:29:00 | 2021-10-15 19:43:00 | Road dirt | 1516 | 15.614101 |
| D1_AA14-1 | 23.99981 | 45.53323 | 2021-08-11 12:23:00 | 2021-09-06 13:48:00 | Road dirt | 1554 | 3.011621 |
| D1_AB11-1 | 24.05055 | 45.60223 | 2021-07-15 13:06:00 | 2021-08-10 10:36:00 | Trail game | 1029 | -18.145098 |
| D1_AB12-2 | 24.03086 | 45.57991 | 2021-09-21 10:04:00 | 2021-10-28 14:45:00 | Trail game | 1230 | -5.843720 |
| D1_AB13-1 | 24.02157 | 45.56658 | 2021-08-04 11:44:00 | 2021-09-21 10:28:00 | Road dirt | 1461 | 24.696217 |
| D1_AC10-1 | 24.09269 | 45.62117 | 2021-07-15 09:54:00 | 2021-08-04 16:05:00 | Road dirt | 1034 | -12.185958 |
# save the dataset as csv file
write.csv(deployment_subset,
"deployment+covariates.csv",
row.names = FALSE)Setting up the season period
This example is based on a single-season project, where a season needs to consider the assumption of closed population. A quick look up on Excel and previous outputs from R code will show you that the earliest deployment date was the 15th July 2021 and Beth deployed cameras during the summer months (July, August, and September) up to the 21st September 2021. We will be focusing on the photographs obtained from the cameras deployed over the summer, starting on the 15th of July and ending on the 21st of September. In other projects you can take a different approach (i.e. shorter or longer period considered as a season), but for the purposes of this case study that is what we will do.
# Step 1: Convert start_date to POSIXct format
deployment_subset$start_date <- as.POSIXct(deployment_subset$start_date, format = "%Y-%m-%d %H:%M:%S")
# Step 2: Filter deployment dataset for start_date up to 21/09/2021
filtered_deployment <- deployment_subset %>%
filter(start_date <= as.POSIXct("2021-09-21 23:59:59", format = "%Y-%m-%d %H:%M:%S"))
# Step 3: Subset camtraps dataset where deployment_id matches the filtered deployment records
filtered_camtraps <- camtraps %>%
filter(deployment_id %in% filtered_deployment$deployment_id)
# Step 4 : Check how many records are kept in the subsets in comparison with the previous
original_deployment_count <- nrow(deployment_subset)
original_camtraps_count <- nrow(camtraps)
filtered_deployment_count <- nrow(filtered_deployment)
filtered_camtraps_count <- nrow(filtered_camtraps)
cat(
" Original deployment records:", original_deployment_count, "\n",
"Number of deployments during the summer:", filtered_deployment_count, "\n\n",
"Original number of detections:", original_camtraps_count, "\n",
"Number of detections for cameras deployed during the summer:", filtered_camtraps_count, "\n"
) Original deployment records: 135
Number of deployments during the summer: 70
Original number of detections: 71726
Number of detections for cameras deployed during the summer: 36162
# save the summer images as csv file
write.csv(filtered_camtraps,
"summer_images.csv",
row.names = FALSE)You can add the deployment period and the number of days when the camera was deployed at the location
# Calculate the duration in days, including both start and end date
filtered_deployment$duration_days <- as.numeric(as.Date(filtered_deployment$end_date) - as.Date(filtered_deployment$start_date)) + 1
# Summarise the range of values obtained
summary(filtered_deployment$duration_days) Min. 1st Qu. Median Mean 3rd Qu. Max.
8.00 17.75 25.50 29.39 38.00 67.00
# Get the first 10 rows
first_10_rows <- head(filtered_deployment, 10)
# Create a nice table
kable(first_10_rows, format = "html", caption = "Deployment Data with covariates and interval") %>%
kable_styling(full_width = FALSE, position = "left")| deployment_id | longitude | latitude | start_date | end_date | feature_type | elevation | ruggedness | duration_days |
|---|---|---|---|---|---|---|---|---|
| D1_AA10-1 | 24.00188 | 45.62046 | 2021-07-20 09:53:00 | 2021-08-09 06:43:00 | Trail game | 1137 | -4.155159 | 21 |
| D1_AA11-1 | 23.98999 | 45.60232 | 2021-07-20 17:37:00 | 2021-08-10 18:57:00 | Road dirt | 1073 | -16.522067 | 22 |
| D1_AA12-1 | 24.00164 | 45.58462 | 2021-08-04 13:05:00 | 2021-09-21 09:11:00 | Road dirt | 1155 | -9.000408 | 49 |
| D1_AA13-2 | 23.98795 | 45.55146 | 2021-09-21 12:29:00 | 2021-10-15 19:43:00 | Road dirt | 1516 | 15.614101 | 25 |
| D1_AA14-1 | 23.99981 | 45.53323 | 2021-08-11 12:23:00 | 2021-09-06 13:48:00 | Road dirt | 1554 | 3.011621 | 27 |
| D1_AB11-1 | 24.05055 | 45.60223 | 2021-07-15 13:06:00 | 2021-08-10 10:36:00 | Trail game | 1029 | -18.145098 | 27 |
| D1_AB12-2 | 24.03086 | 45.57991 | 2021-09-21 10:04:00 | 2021-10-28 14:45:00 | Trail game | 1230 | -5.843720 | 38 |
| D1_AB13-1 | 24.02157 | 45.56658 | 2021-08-04 11:44:00 | 2021-09-21 10:28:00 | Road dirt | 1461 | 24.696217 | 49 |
| D1_AC10-1 | 24.09269 | 45.62117 | 2021-07-15 09:54:00 | 2021-08-04 16:05:00 | Road dirt | 1034 | -12.185958 | 21 |
| D1_AC10-2 | 24.09091 | 45.62390 | 2021-09-21 15:18:00 | 2021-10-15 09:28:00 | Road dirt | 1034 | -12.185958 | 25 |
# save the summer deployments as csv file
write.csv(filtered_deployment,
"summer_deployments.csv",
row.names = FALSE)Effort as Detection Covariate
Effort can be used as a detection probability variable. Camera effort can be defined as the number of days a camera was active during a sampling occasion. Effort can affect species detection probability (Wevers et al. 2021). You will see some papers using this covariate, others do not. The following code will allow you to obtain this variable and save it as an independent dataset.
- Ensure dates are in proper format
filtered_deployment <- filtered_deployment %>%
mutate(start_date = as.Date(start_date, format = "%Y-%m-%d"),
end_date = as.Date(end_date, format = "%Y-%m-%d"))Converts start_date and end_date columns in the filtered_deployment dataframe into Date format to ensure proper date calculations.
- Calculate duration in days
filtered_deployment <- filtered_deployment %>%
mutate(duration_days = as.numeric(end_date - start_date) + 1)Adds a duration_days column to compute the total number of days each deployment was active.
The +1 ensures the start day is included.
- Determine the overall Start date
overall_start_date <- as.Date(min(filtered_deployment$start_date))Finds the earliest start_date across all deployments to use as a reference point for period calculations.
- Initialise the effort dataset
effort_df <- data.frame(deployment_id = character(),
S01 = integer(), SO2 = integer(),
SO3 = integer(), S04 = integer(),
S05 = integer(), SO6 = integer(),
S07 = integer(), S08 = integer(),
SO9 = integer(), S010 = integer(),
S011 = integer(),
start_date = as.Date(character()),
end_date = as.Date(character()),
stringsAsFactors = FALSE)Creates an empty effort_df dataframe with columns for deployment IDs and 11 time periods (S01 to S011).
Includes start_date and end_date columns for later merging.
- Define period length
period_length <- 10- Loop through each deployment
# Loop through each deployment to calculate effort for each 10-day period (SO1 to SO11, to cover all deployment period for cameras deployed up to the 21st of September)
for (index in 1:nrow(filtered_deployment)) {
deployment_id <- filtered_deployment$deployment_id[index]
start_date <- filtered_deployment$start_date[index]
end_date <- filtered_deployment$end_date[index]
total_days <- as.numeric(difftime(end_date, start_date, units = "days")) + 1
# Initialize an array to hold the days for each period
period_days <- rep(NA, 11) # S01 to S011, this covers all cameras deployed until the 21st of September
# Loop through each 10-day period (SO1 to SO11)
for (period in 0:10) {
period_start <- overall_start_date + days(period * period_length)
period_end <- period_start + days(period_length - 1)
# Check if the deployment overlaps with the current period
if (period_end >= start_date && period_start <= end_date) {
active_days <- max(0, as.numeric(difftime(min(end_date, period_end), max(start_date, period_start), units = "days")) + 1)
period_days[period + 1] <- as.integer(active_days) # Convert to integer to avoid decimals
}
}
# Combine results into the effort_df
effort_df <- rbind(effort_df, data.frame(deployment_id, t(period_days), stringsAsFactors = FALSE))
}Iterates through each deployment in
filtered_deployment.Extracts
deployment_id,start_date, andend_date.Calculates
total_daysfor the deployment.Loops through each 10-day period.
Defines
period_startandperiod_endbased on the overall start date and the current period.Checks if the deployment overlaps with the period:
Uses
maxandminto compute the overlap duration.Adds the active days in the period to
period_days.
Converts the
period_daysarray into a row and appends it toeffort_df.
- Rename period columns
colnames(effort_df)[-1] <- paste0("S0", 1:11)- Add metadata
effort_df <- effort_df %>%
left_join(filtered_deployment %>%
dplyr::select(deployment_id, start_date, end_date, duration_days),
by = "deployment_id")Merges start_date, end_date, and duration_days into effort_df.
- Sort by start date
effort_df <- effort_df %>%
arrange(start_date)- Finish all off
# Save the updated effort_df as a CSV file
write.csv(effort_df,
"effort_data.csv",
row.names = FALSE)
# Get the first 20 rows
first_20_rows <- head(effort_df, 20)
# Create a nice table for visualisation
kable(first_20_rows, format = "html", caption = "Effort data over 105 days, split by 10 days ocassions") %>%
kable_styling(full_width = FALSE, position = "left")| deployment_id | S01 | S02 | S03 | S04 | S05 | S06 | S07 | S08 | S09 | S010 | S011 | start_date | end_date | duration_days |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| D1_AB11-1 | 10 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-15 | 2021-08-10 | 27 |
| D1_AC10-1 | 10 | 10 | 1 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-15 | 2021-08-04 | 21 |
| D1_AC11-1 | 10 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-15 | 2021-08-10 | 27 |
| D1_AC11-2 | 10 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-15 | 2021-08-10 | 27 |
| D1_AD10-1 | 10 | 10 | 1 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-15 | 2021-08-04 | 21 |
| D1_AA10-1 | 5 | 10 | 6 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-09 | 21 |
| D1_AA11-1 | 5 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-10 | 22 |
| D1_W13-1 | 5 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-10 | 22 |
| D1_Y11-1 | 5 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-10 | 22 |
| D1_Z10-1 | 5 | 3 | NA | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-07-27 | 8 |
| D1_Z11-1 | 5 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-10 | 22 |
| D1_Z12-1 | 5 | 10 | 7 | NA | NA | NA | NA | NA | NA | NA | NA | 2021-07-20 | 2021-08-10 | 22 |
| D1_AA12-1 | NA | NA | 10 | 10 | 10 | 10 | 9 | NA | NA | NA | NA | 2021-08-04 | 2021-09-21 | 49 |
| D1_AB13-1 | NA | NA | 10 | 10 | 10 | 10 | 9 | NA | NA | NA | NA | 2021-08-04 | 2021-09-21 | 49 |
| D2_AC10-1 | NA | NA | 10 | 10 | 4 | NA | NA | NA | NA | NA | NA | 2021-08-04 | 2021-08-27 | 24 |
| D2_AD10-1 | NA | NA | 10 | 10 | 10 | 10 | 9 | NA | NA | NA | NA | 2021-08-04 | 2021-09-21 | 49 |
| D1_R12-1 | NA | NA | 9 | 10 | 2 | NA | NA | NA | NA | NA | NA | 2021-08-05 | 2021-08-25 | 21 |
| D1_S12-1 | NA | NA | 9 | 10 | 2 | NA | NA | NA | NA | NA | NA | 2021-08-05 | 2021-08-25 | 21 |
| D1_T12-1 | NA | NA | 9 | 10 | 2 | NA | NA | NA | NA | NA | NA | 2021-08-05 | 2021-08-25 | 21 |
| D1_W13-2 | NA | NA | 4 | 10 | NA | NA | NA | NA | NA | NA | NA | 2021-08-10 | 2021-08-23 | 14 |
The detection matrix
For single-season occupancy models, we need the structure to include a SINGLE row for each deployment, with a column stating the detection (i.e. 0=no detection, 1=detection) for each sampling occasion and the columns containing the covariates of interest. This data structure should look like this:
To obtain this structure, we will need to move things around. You can do this manually and if the dataset is not extensive it should not take you too long. Also it might be appropriate if you want to have a good sense for the nature of the data and reflect on effort and potential results. If you prefer to automatise the process, you can use the R code below, which includes an extensive explanation of what is going on :-)
Libraries Loaded:
dplyr: For data manipulation using pipes (
%>%) and functions likefilter(),mutate(), andselect().lubridate: For handling dates and time calculations, making it easier to manipulate date formats.
Code Breakdown:
Ensure Start and End Dates Are in Date Format:
filtered_deployment <- filtered_deployment %>%
mutate(start_date = as.Date(start_date, format = "%Y-%m-%d"),
end_date = as.Date(end_date, format = "%Y-%m-%d"))- Converts the
start_dateandend_datecolumns of thefiltered_deploymentdataset intoDateformat. This ensures the dates are consistent for comparison in subsequent steps.
Get the Absolute Earliest Start Date:
overall_start_date <- as.Date(min(filtered_deployment$start_date))- Finds the earliest deployment start date across all rows of the
filtered_deploymentdataset. This date will be used as a reference point to define periods for the detection matrix.
Define the Period Length:
period_length <- 10Sets the length of each period to 10 days. These periods are used to group the data into intervals (Sampling Ocassions, S01 to S011) for occupancy modeling.
Create the sheep_detection Dataset:
sheep_detection <- filtered_deployment %>%
dplyr::select(deployment_id, longitude, latitude, feature_type, elevation, ruggedness)- Extracts key columns (
deployment_id,longitude,latitude, etc.) from thefiltered_deploymentdataset (which is a summer subset of the original dataset) to form a new dataset,sheep_detection. This dataset will eventually contain the detection matrix.
Initialize the Period Columns:
sheep_detection <- sheep_detection %>%
mutate(SO1 = NA, SO2 = NA, SO3 = NA, SO4 = NA, SO5 = NA,
SO6 = NA, SO7 = NA, SO8 = NA, SO9 = NA, SO10 = NA,
SO11 = NA
)- Adds five columns (
SO1toSO11) to represent the detection status of “European sheep” in each 10-day period. These are initialised withNA(this means that by default, periods with no overlap will stay asNA).
Loop Through Each Deployment:
# Loop through each deployment and check for sheep detections
for (i in 1:nrow(sheep_detection)) {
current_deployment_id <- sheep_detection$deployment_id[i] # to avoid using the same variable name for both the dataset and the loop variable
# Get start and end date for the current deployment
start_date <- filtered_deployment$start_date[filtered_deployment$deployment_id == current_deployment_id][1]
end_date <- filtered_deployment$end_date[filtered_deployment$deployment_id == current_deployment_id][1]
for (period in 1:11) {
period_start <- overall_start_date + days((period - 1) * period_length)
period_end <- period_start + days(period_length - 1)
if (max(as.Date(period_start), as.Date(start_date)) <= min(as.Date(period_end), as.Date(end_date))) {
# Filter records specifically for the current deployment
sheep_count <- filtered_camtraps %>%
filter(deployment_id == current_deployment_id,
common_name == "Domestic Sheep",
as.POSIXct(timestamp) >= as.POSIXct(period_start) &
as.POSIXct(timestamp) <= as.POSIXct(period_end))
# Count occurrences
sheep_count_num <- nrow(sheep_count)
# Assign count to detection dataframe
sheep_detection[[paste0("SO", period)]][i] <- ifelse(sheep_count_num > 0, 1, 0)
} else {
sheep_detection[[paste0("SO", period)]][i] <- NA
}
}
}Iterates over each row of the sheep_detection dataset, corresponding to each deployment. For each deployment, it performs the following steps:
Extract Deployment-Specific Dates:
For each deployment, retrieves the
start_dateandend_dateby matching thedeployment_id. The[1]ensures that only a single value is extracted, even if there are multiple matches.Loop Through the S01 to S05 Periods:
Loops over five 21-day periods (S01 to S011), dynamically setting the column name for each period (
period_col).Define Period Start and End Dates
For each period, defines its start and end dates by adding the appropriate number of days to the
overall_start_date. This ensures each period is 10 days long.Check If Deployment Overlaps with Period:
Checks if the deployment’s start and end dates overlap with the current period. If so, the code proceeds to check for detections during this period.
Count sheep Detections for the Period:
Filters the
filtered_camtrapsdataset (which contains camera trap data) to count how many times “Domestic Sheep” was detected during the current period for the current deployment. This is done by filtering on:The matching
deployment_id.The species name
common_namebeing “Domestic Sheep”.The
timestampfalling within the period’s start and end dates.
Update the Period Column if sheep Was Detected:
If any “European sheep” detections were found (i.e.,
sheep_count > 0), the value for the respective period column (SO1toSO5) is set to 1, indicating detection. If there are no detections but there was overlap, the value is set to0. If they do not overlap, the value remainsNA.
Save the sheep_detection Dataset as a CSV File and visualise outputs:
write.csv(sheep_detection,
"sheep_detection.csv",
row.names = FALSE)
# Get the first 10 rows
first_10_rows_sheep <- head(sheep_detection, 10)
# Create a nice table for visualization
kable(first_10_rows_sheep, format = "html", caption = "Detection matrix for sheep over 105 days, split by 10-day occasions") %>%
kable_styling(full_width = FALSE, position = "left")| deployment_id | longitude | latitude | feature_type | elevation | ruggedness | SO1 | SO2 | SO3 | SO4 | SO5 | SO6 | SO7 | SO8 | SO9 | SO10 | SO11 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| D1_AA10-1 | 24.00188 | 45.62046 | Trail game | 1137 | -4.155159 | 0 | 0 | 0 | NA | NA | NA | NA | NA | NA | NA | NA |
| D1_AA11-1 | 23.98999 | 45.60232 | Road dirt | 1073 | -16.522067 | 0 | 0 | 0 | NA | NA | NA | NA | NA | NA | NA | NA |
| D1_AA12-1 | 24.00164 | 45.58462 | Road dirt | 1155 | -9.000408 | NA | NA | 0 | 1 | 0 | 0 | 0 | NA | NA | NA | NA |
| D1_AA13-2 | 23.98795 | 45.55146 | Road dirt | 1516 | 15.614101 | NA | NA | NA | NA | NA | NA | 0 | 0 | 0 | 0 | NA |
| D1_AA14-1 | 23.99981 | 45.53323 | Road dirt | 1554 | 3.011621 | NA | NA | 0 | 1 | 0 | 0 | NA | NA | NA | NA | NA |
| D1_AB11-1 | 24.05055 | 45.60223 | Trail game | 1029 | -18.145098 | 0 | 0 | 0 | NA | NA | NA | NA | NA | NA | NA | NA |
| D1_AB12-2 | 24.03086 | 45.57991 | Trail game | 1230 | -5.843720 | NA | NA | NA | NA | NA | NA | 0 | 0 | 0 | 0 | 0 |
| D1_AB13-1 | 24.02157 | 45.56658 | Road dirt | 1461 | 24.696217 | NA | NA | 0 | 1 | 0 | 0 | 0 | NA | NA | NA | NA |
| D1_AC10-1 | 24.09269 | 45.62117 | Road dirt | 1034 | -12.185958 | 0 | 0 | 0 | NA | NA | NA | NA | NA | NA | NA | NA |
| D1_AC10-2 | 24.09091 | 45.62390 | Road dirt | 1034 | -12.185958 | NA | NA | NA | NA | NA | NA | 0 | 0 | 0 | 0 | NA |