I'm a big fan of spOccupancy and how it can take into account spatial autocorrelation. Been on the 'accounting for autocorrelation' hype train since I started using ctmm last year for my MSc thesis. Thanks for making this package!
I've been using spOccupancy for trhe past few months for work here in Taiwan to produce occupancy estimates of some of the endangered animals here (camera trap data). I've used the examples provided on the spOccupancy website, alongside your lecture I found online, to teach myself the package (along with ChatGPT, as I imagine most of us do nowdays).
2) Is there a simple way to calculate detection probabilities for each replicate/season for a spOccupancy model? I see that in R packages like unmarked, there are simple functions to calculate the detection probability, just as there are with the occurrence probability. But I haven't found a clear and easy way to calculate detection probabilities with spOccupancy. I'm wondering if I've colossally missed something while learning this package, or if a function/small code snippet for calculating detection probabilities is something that is on the to-do list for spOccupancy!
Based on the spOccupancy examples, there is a clear way to calculate mean occupancy probability e.g.:
mean(psi.mean_out <- apply(out$psi.samples, 2, mean)). gives mean occupancy for the entire season (single season model, in my example we have 3 replicates).
The same code applied to a single-species multi-season model would give the average occupancy for the entire multiseason model, while replacing the 2 with a 3 gives the summarised occupancy for each season of the multiseason model.
Since I couldn't see a clear way of calculating detection probabilities with spOccupancy, using ChatGPT, I devised the following code (see below this question). I ran my same data through unmarked and got fairly similar occupancy estimates, the detection estimates were still ROUGHLY similar in their patterns but definitely not as much as the occupancy estimates.
# calculating detection probability per primary time period
#now with with multiple det covs
# Extract alpha samples for detection coefficients
out_awb_2023_aut_B_sp_exp
# det.formula = ~scale(DC1) + I(scale(DC1^2)) +
# scale(DC2) + I(scale(DC2^2)) + scale(DC3) + I(scale(DC3)^2) +
# scale(DC4) + I(scale(DC4)^2)
alpha_samples_awb_2023_aut_B <- out_awb_2023_aut_B_sp_exp$alpha.samples
# Get detection covariates from the data structure
DC1_covariates_awb_2023_aut_B <- data.awb_2023_aut_B$det.covs$DC1
DC2_covariates_awb_2023_aut_B <- data.awb_2023_aut_B$det.covs$DC2
DC3_covariates_awb_2023_aut_B <- data.awb_2023_aut_B$det.covs$DC3
DC4_covariates_awb_2023_aut_B <- data.awb_2023_aut_B$det.covs$DC4
alpha_samples_awb_2023_aut_B
head(alpha_samples_awb_2023_aut_B)
# Extract dimensions
num_samples_awb_2023_aut_B <- nrow(alpha_samples_awb_2023_aut_B) # Number of posterior samples
num_sites_awb_2023_aut_B <- dim(DC1_covariates_awb_2023_aut_B)[1] # Number of sites
num_replicates_awb_2023_aut_B <- dim(DC1_covariates_awb_2023_aut_B)[2] # Number of replicates
str(DC1_covariates_awb_2023_aut_B)
# Initialize array to store detection probabilities
detection_probs_awb_2023_aut_B <- array(NA, dim = c(num_samples_awb_2023_aut_B,
num_sites_awb_2023_aut_B,
num_replicates_awb_2023_aut_B))
detection_probs_awb_2023_aut_B
# Loop through each posterior sample
for (s in 1:num_samples_awb_2023_aut_B) {
# Get the s-th set of detection coefficients
alpha_s_awb_2023_aut_B <- alpha_samples_awb_2023_aut_B[s, ]
# Compute detection probability for each site, season, and replicate
for (site in 1:num_sites_awb_2023_aut_B){
for (rep in 1:num_replicates_awb_2023_aut_B) {
# Extract covariate values for this site, season, and replicate
DC1_value_awb_2023_aut_B <- DC1_covariates_awb_2023_aut_B[site, rep]
DC2_value_awb_2023_aut_B <- DC2_covariates_awb_2023_aut_B[site, rep]
DC3_value_awb_2023_aut_B <- DC3_covariates_awb_2023_aut_B[site, rep]
DC4_value_awb_2023_aut_B <- DC4_covariates_awb_2023_aut_B[site, rep]
# Skip if any covariate values contain NAs
if (
is.na(DC1_value_awb_2023_aut_B) ||
is.na(DC2_value_awb_2023_aut_B)) next
# Compute the linear predictor (eta)
eta_awb_2023_aut_B <- (alpha_s_awb_2023_aut_B[1]) +
(alpha_s_awb_2023_aut_B[2] * DC1_value_awb_2023_aut_B) + #DC1
(alpha_s_awb_2023_aut_B[3] * (DC1_value_awb_2023_aut_B^2)) + #DC1^2
(alpha_s_awb_2023_aut_B[4] * DC2_value_awb_2023_aut_B) + #DC2
(alpha_s_awb_2023_aut_B[5] * (DC2_value_awb_2023_aut_B^2)) + #DC2^2
(alpha_s_awb_2023_aut_B[4] * DC3_value_awb_2023_aut_B) + #DC3
(alpha_s_awb_2023_aut_B[5] * (DC3_value_awb_2023_aut_B^2)) + #DC3^2
(alpha_s_awb_2023_aut_B[4] * DC4_value_awb_2023_aut_B) + #DC4
(alpha_s_awb_2023_aut_B[5] * (DC4_value_awb_2023_aut_B^2)) #DC4^2
# Compute detection probability
detection_probs_awb_2023_aut_B[s, site, rep] <- 1 / (1 + exp(-eta_awb_2023_aut_B))
}
}
}
detection_probs_awb_2023_aut_B
# summarize the detection probabilities, e.g., mean across samples
mean_detection_probs_awb_2023_aut_B <- apply(detection_probs_awb_2023_aut_B, c(2,3), mean, na.rm = TRUE)
mean_detection_probs_awb_2023_aut_B
str(detection_probs_awb_2023_aut_B)
class(detection_probs_awb_2023_aut_B)
# Calculate average detection probability per season
avg_detection_probs_per_replicate_awb_2023_aut_B <- apply(mean_detection_probs_awb_2023_aut_B, 2, function(x) mean(x, na.rm = TRUE))
# Print the result
avg_detection_probs_per_replicate_awb_2023_aut_B
# 0.7483477 0.7483494 0.7483454
data.awb_2023_aut_B$y