Reference and Disclaimer: For this exercise, I have used explanation and major chunk of codes from the book Spatial Ecology and Conservation Modeling by Robert Fletcher & Marie-Josée Fortin.
Load the necessary packages
rm(list = ls())
## First specify the packages of interest
= c("stringr","rgdal", "spdep", "lme4","vegan", "mgcv", "MASS", "spaMM", "deldir", "dismo", "spatialreg", "huxtable","INLA")
packages
## Now load or install&load all
<- lapply(
package.check
packages,FUN = function(x) {
if (!require(x, character.only = TRUE)) {
install.packages(x, dependencies = TRUE)
library(x, character.only = TRUE)
}
} )
Load the raster data and the point data to be analysed
<- raster("./SpaStatAssign/CWT_regiona_10mDEM.tif")
elev
= readOGR("./SpaStatAssign/SpaStatData.gdb","BAWW2021_PointCounts800mgrid") point.data
Checking the projection for the DEM layer
proj4string(elev)
## [1] "+proj=utm +zone=17 +datum=NAD83 +units=m +no_defs"
Checking the projection for the point data
proj4string(point.data)
## [1] "+proj=utm +zone=17 +datum=NAD83 +units=m +no_defs"
head(point.data)
ID | x1 | x2 | PointCountCapName | detectP1 | detectP2 | detectP3 | detectP4 | Detection |
---|---|---|---|---|---|---|---|---|
pcCoweeta001 | 2.76e+05 | 3.88e+06 | PCCow001 | 0 | 0 | 1 | 0 | 1 |
pcCoweeta002 | 2.75e+05 | 3.88e+06 | PCCow002 | 1 | 1 | 0 | 0 | 1 |
pcCoweeta002 | 2.75e+05 | 3.88e+06 | PCCow002 | 1 | 1 | 1 | 0 | 1 |
pcCoweeta003 | 2.75e+05 | 3.88e+06 | PCCow003 | 0 | 0 | 0 | 1 | 1 |
pcCoweeta004 | 2.76e+05 | 3.88e+06 | PCCow004 | 1 | 0 | 1 | 0 | 1 |
pcCoweeta005 | 2.76e+05 | 3.88e+06 | PCCow005 | 1 | 1 | 1 | 1 | 1 |
Using terrain() we derive other variables of interest: slope and aspect. We merge all the layers into a single raster stack using stack()
#create slope, aspect layers from elevation
<- terrain(elev, opt=c("slope", "aspect"))
elev.terr #make a multilayered file for extraction
<- stack(elev, elev.terr) #merge the slope and aspect layers into a single raster object that holds all raster layers
layers names(layers) <- c("elev", "slope", "aspect")
Plotting the raster stack
plot(layers)
Plotting the presence and absence of Black and White Warbler. We are concerned with the detection of the BAWW rather than the type of BAWW detected here
plot(elev)
points(point.data[point.data$Detection==1, c("x1","x2")], col="red") #plots the presence points
points(point.data[point.data$Detection==0, c("x1","x2")], col="black") #plots the absence points
We use extract() from raster package to extract covariate values from layers corresponding to the locations from the survey data of BAWW and merge them with the point data
#extract GIS data at sampling points
<- cbind(point.data$x1, point.data$x2)
coords colnames(coords) <- c("x", "y")
<- raster::extract(x=layers, y=coords) # If y represents points, extract returns the values of a Raster* object for the cells in which a set of points fall.
land.cov <- cbind(point.data,land.cov) point.data
Since centering and scaling can help improve model convergence and facilitates comparing coefficients for different parameter, we scale our predictors
$elevs <- scale(point.data$elev, center = T, scale = T)
point.data$slopes <- scale(point.data$slope, center = T, scale = T)
point.data$aspects <- scale(point.data$aspect, center = T, scale = T) point.data
<- glm(Detection ~ elev, family="binomial", data=point.data)
model_elev <- glm(Detection ~ slope, family="binomial", data=point.data)
model_slope <- glm(Detection ~ elev + slope + aspect, family="binomial", data=point.data)
model_all <- glm(Detection ~ poly(slope,2),family="binomial", data=point.data) model_slope2
= list("Elevation only" = model_elev,
model_tbl "Slope only" = model_slope,
"All" = model_all,
"Slope square" = model_slope2)
<- names(coef(model_tbl[[1]]))[stringr::str_detect(names(coef(model_tbl[[1]])), "vdc")]
coefs
<- huxreg(model_tbl,number_format = 3, omit_coefs =coefs) %>%
huxtable set_caption("Table: Logistic Regression Models")
huxtable
Elevation only | Slope only | All | Slope square | |
---|---|---|---|---|
(Intercept) | 0.676Â | -0.859Â Â Â | -1.536Â Â Â | 1.014 *** |
(1.192) | (0.571)Â Â | (1.509)Â Â | (0.204)Â Â Â | |
elev | 0.000Â | Â Â Â Â Â Â Â | 0.001Â Â Â | Â Â Â Â Â Â Â Â |
(0.001) | Â Â Â Â Â Â Â | (0.001)Â Â | Â Â Â Â Â Â Â Â | |
slope | Â Â Â Â Â | 4.325 ** | 4.384 ** | Â Â Â Â Â Â Â Â |
     | (1.359)  | (1.441)  |         | |
aspect | Â Â Â Â Â | Â Â Â Â Â Â Â | -0.183Â Â Â | Â Â Â Â Â Â Â Â |
     |        | (0.110)  |         | |
poly(slope, 2)1 | Â Â Â Â Â | Â Â Â Â Â Â Â | Â Â Â Â Â Â Â | 7.822 **Â |
     |        |        | (2.581)   | |
poly(slope, 2)2 | Â Â Â Â Â | Â Â Â Â Â Â Â | Â Â Â Â Â Â Â | -0.032Â Â Â Â |
     |        |        | (2.494)   | |
N | 141Â Â Â Â Â | 141Â Â Â Â Â Â Â | 141Â Â Â Â Â Â Â | 141Â Â Â Â Â Â Â Â |
logLik | -84.070Â | -78.454Â Â Â | -76.608Â Â Â | -78.454Â Â Â Â |
AIC | 172.140Â | 160.908Â Â Â | 161.216Â Â Â | 162.908Â Â Â Â |
*** p < 0.001; ** p < 0.01; * p < 0.05. |
From the above model comparison we have some evidence that the BAWW spotting increases with increasing slope. We see that the slope term is positive and significant at 1%. Considering the AIC along side the significance, I would prefer Slope only model as the number of variable used is smaller than other models.
We create a new dataset and use Slope only model to predict the relationship
<- seq(min(point.data$slope), max(point.data$slope), length=15)
Slope <- data.frame(slope=Slope)
newdata #Predict onto newdata
<- predict(model_slope, newdata=newdata, type= "link", se=T)
glm.pred # Creating 95% confidence interval
<- glm.pred$fit + 1.96*glm.pred$se.fit
ucl <- glm.pred$fit - 1.96*glm.pred$se.fit lcl
Back-transforming the predictions from link to the probability scale
<- data.frame(newdata, pred=plogis(glm.pred$fit), lcl=plogis(lcl), ucl=plogis(ucl)) glm.newdata
Plotting the predictions of the model onto new data in probability scale
plot(glm.newdata$slope, glm.newdata$pred, ylim=c(0,2), xlab="Slope", ylab="Prob. Occurrence")
lines(glm.newdata$slope, glm.newdata$lcl)
lines(glm.newdata$slope, glm.newdata$ucl)
#Map the model
<- predict(model=model_slope, object=layers, type="response")
glm.raster <= exp(glm.raster)/(1+exp(glm.raster)) glm.raster
## class : RasterLayer
## dimensions : 952, 1285, 1223320 (nrow, ncol, ncell)
## resolution : 9.236852, 9.236852 (x, y)
## extent : 269816.1, 281685.4, 3876588, 3885381 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=17 +datum=NAD83 +units=m +no_defs
## source : memory
## names : layer
## values : 0, 1 (min, max)
plot(glm.raster, xlab = "Longitude", ylab = "Latitude")
We say that there exist spatial dependence: Spotting BMWW with increasing slope
Thanks!!!