library(readr)
library(INLA)
library(rgeos)
library(rgdal)
library(maptools)
library(splancs)
library(dplyr)
library(lubridate)
#Import the dataset
setwd("")
MergedPRvars <- read_csv("")
#Import the workspace image with the mesh and locations already made
load("")
k <- 847 #set the number of time points in weeks
coords <- as.matrix(loc@coords) #Get the 73 location coordinates
#Make k independent realizations of the spatial mesh for each coordinate
rspde <- function(coords, kappa, variance=1, alpha=2, n=1, mesh,
verbose=FALSE, seed, return.attributes=FALSE) {
t0 <- Sys.time()
theta <- c(-0.5*log(4*pi*variance*kappa^2), log(kappa))
if (verbose) cat('theta =', theta, '\n')
if (missing(mesh)) {
mesh.pars <- c(0.5, 1, 0.1, 0.5, 1)*sqrt(alpha-ncol(coords)/2)/kappa
if (verbose) cat('mesh.pars =', mesh.pars, '\n')
attributes <- list(
mesh=inla.mesh.2d(,
coords[chull(coords), ], max.edge=mesh.pars[1:2],
cutoff=mesh.pars[3], offset=mesh.pars[4:5]))
if (verbose) cat('n.mesh =', attributes$mesh$n, '\n')
}
else attributes <- list(mesh=mesh)
attributes$spde <- inla.spde2.matern(attributes$mesh, alpha=alpha)
attributes$Q <- inla.spde2.precision(attributes$spde, theta=theta)
attributes$A <- inla.mesh.project(mesh=attributes$mesh, loc=coords)$A
if (n==1)
result <- drop(attributes$A%*%inla.qsample(
Q=attributes$Q,
constr=attributes$spde$f$extraconstr))
t1 <- Sys.time()
result <- inla.qsample(n, attributes$Q,
seed=ifelse(missing(seed), 0, seed),
constr=attributes$spde$f$extraconstr)
if (nrow(result)<nrow(attributes$A)) {
result <- rbind(result, matrix(
NA, nrow(attributes$A)-nrow(result), ncol(result)))
dimnames(result)[[1]] <- paste('x', 1:nrow(result), sep='')
for (j in 1:ncol(result))
result[, j] <- drop(attributes$A%*%
result[1:ncol(attributes$A),j])
}
else {
for (j in 1:ncol(result))
result[1:nrow(attributes$A), j] <-
drop(attributes$A%*%result[,j])
result <- result[1:nrow(attributes$A), ]
}
t2 <- Sys.time()
attributes$cpu <- c(prep=t1-t0, sample=t2-t1, total=t2-t0)
if (return.attributes)
attributes(result) <- c(attributes(result), attributes)
return(drop(result))
}
params <- c(variance=1, kappa=sqrt(8*1)/5000) #kappa = sqrt(8*nu)/range, where range = 5 km in this case and nu is 1 since it's alpha/dimensions of coords, which are both 2
x.k <- rspde(coords, kappa=params[2], variance=params[1], n=k,
mesh=mesh, return.attributes=TRUE)
dim(x.k)
#Define autoregressive parameter
rho <- 0.95
#Get correlated sample over time
x <- x.k
for (j in 2:k)
x[,j] <- rho*x[,j-1] + sqrt(1-rho^2)*x.k[,j]
n <- nrow(coords) #number of observations sites
#Get the covariates
vars <- data.frame(
rlag99 = as.factor(MergedPRvars$rlag99),
ppl_FldPer = (MergedPRvars$ppl_FldPer),
SwgPerc = (MergedPRvars$SwgPerc),
KarstPerc = (MergedPRvars$KarstPerc),
X2010mmha_Huc10 = (MergedPRvars$X2010mmha_Huc10), #variable names can't start with a number so add an X
wk = rep(1:k, times=n))
vars[,2:5] <- scale(vars[,2:5])
#Set beta coefficient values for each of the predictors
b1 = c(0,0.2, 0.4, 0.6) #Since this is a factor, for simplicity we will multiply and assume that each add'l rain event is equal in magnitude, not a realistic assumption!
b2 = 0.4
b3 = -0.4
b4 = -0.3
b5 = 0.1
sd.y <-0.1 #set a small standard deviation for each observation, random chance
y <- b1[unclass(vars$rlag99)] + b2*vars$ppl_FldPer + b3*vars$SwgPerc + b4*vars$KarstPerc + b5*vars$X2010mmha_Huc10 + x + rnorm(n*k, 0, sd.y)
#Change the response to a binomial rather than in logits, using ifelse() to set zero inflation to 0.7
y[] <- apply(y, c(1,2), FUN= function(x) ifelse(rbinom(n=1, size=1, prob = 0.1) > 0, 0, rbinom(n=1, prob=exp(x)/(1+exp(x)), size = 1)))
#####Create the INLA SPDE and run the model
min.width <- min(c(diff(range(mesh$loc[, 1])), diff(range(mesh$loc[, 2])))) #Minimum width of the study area in km
spde <- inla.spde2.pcmatern(
mesh=mesh, alpha=2, ### mesh and smoothness parameter
prior.range=c(min.width/2, 0.5), ### P(range<(half the minimum width of study area in km)=0.5
prior.sigma=c(1, 0.5) ### P(sigma>1)=0.5, note that we know there is no spatial effect present
)
#Create the projector matrix without week grouping
obs.locations <- as.matrix(rep(loc@coords[,1], each=847),rep(loc@coords[,2], each=847))
A <- inla.spde.make.A(mesh, loc=obs.locations)
#Create the stack
stack <- inla.stack(data=list(y=as.vector(y)), #This takes the responses from the matrix y defined in the simulation earlier
A=list(A,1),
effect=list(list(spatial = 1:spde$n.spde),data.frame(vars)))
#Define prior for AR1
h.spec <- list(theta=list(prior='pccor1', param=c(0.5, 0.5))) #P(cor > 0.5) = 0.5
#Define the formula
formula <- y ~ 0 + rlag99 + ppl_FldPer + SwgPerc + KarstPerc + X2010mmha_Huc10 +
f(spatial, model=spde) +
f(wk, model = 'ar1', hyper=h.spec)
#Define prior for precision
prec.prior <- list(prior='pc.prec', param=c(1, 0.01))
result<- inla(formula,
family="zeroinflated.binomial.1", #We use Type 1 because we have "true" zero values for Y
data=inla.stack.data(stack),
control.predictor=list(compute=TRUE, A=inla.stack.A(stack), link = 1), #link = 1 scales the fitted values with the logit link
control.family=list(link='logit',hyper=list(theta=prec.prior)),
control.inla=list(int.strategy='eb'),
control.fixed=list(expand.factor.strategy ='inla'))
#Improve estimation of hyperparameters by rerunning the model, using the previous run's estimates as the starting point
#inla.rerun(result)
summary(result)