Introduction
Finally we will be running a model that combines data from marked and unmarked individuals AND estimates the overall number of individuals \(N\). Similar to the regular capture-recapture model, we will have to assume that there are \(\tilde N\) potential individuals, of which only a fraction \(\pi\) of them actually exist. Thus, the status of each individual is given by a binary variable \(w_i (i=1,...,\tilde N)\). This status variable is equal to 1 if the animal exists and 0 otherwise. We assume that:
\[w_i \sim Bernoulli (\pi) \]
Notice that in this model, \(\pi\) is the proportion of potential individuals that truly exist. Therefore, our estimate of the true population size \(\hat N\) is given by the number of potential individuals \(\tilde N\) times \(\pi\):
\[\hat N = \tilde N \times \pi\]
Furthermore, now we can modify our likelihood for the unmarked individuals in the following way:
\[n_j =\sum_{i=1}^\tilde N \sum_{k=1}^k z_{ijk} \sim Poisson(K \times \sum_{i=1}^\tilde N w_i\lambda_{ij}) \]
Simulating data for model 4
The code to simulate data for this model is identical to that used for model 3. The only difference will be within the JAGS model due to the fact that model 4 estimates the number of individuals whereas model 3 assumed that this was known.
rm(list=ls())
library('ggplot2')
set.seed(1)
=5
sig2=10
lambda0=ymax=100
xmax=20
nind=5
nind.marked=nind-nind.marked
nind.unmark=data.frame(x=runif(nind,min=25,max=75),
coord.acentery=runif(nind,min=25,max=75))
plot(y~x,data=coord.acenter,xlim=c(0,xmax),ylim=c(0,ymax))
=25 #number of traps
ntraps=seq(from=1,to=xmax,length.out=5)
tmp=expand.grid(x=tmp,
coord.trapsy=tmp)
points(y~x,data=coord.traps,col='red',pch=19,cex=0.5)
=10 #encounter times
ntimes
#calculate distances
=matrix(NA,ntraps,nind)
dist1for (j in 1:ntraps){
for (i in 1:nind){
=(coord.traps$x[j]-coord.acenter$x[i])^2
x2=(coord.traps$y[j]-coord.acenter$y[i])^2
y2=sqrt(x2+y2)
dist1[j,i]
}
}# dist1a=proxy::dist(x=coord.traps,y=coord.acenter)
# unique(dist1-dist1a)
#generate data
=array(NA,dim=c(nind,ntraps,ntimes))
zarrayfor (t1 in 1:ntimes){
=matrix(NA,ntraps,nind)
zfor (i in 1:nind){
=exp(-dist1[,i]/sig2)
g=rpois(ntraps,lambda0*g)
z[,i]=z[,i]
zarray[i,,t1]
}
}
#separate marked data
=1:nind.marked
ind.marked=(nind.marked+1):nind
ind.unmarked=zarray[ind.marked,,]
zarray.marked=zarray[ind.unmarked,,]
zarray.unmarked
#calculate summary for marked and unmarked
=apply(zarray.unmarked,2,sum)
nvec.unmarked=apply(zarray.marked,c(1,2),sum) zmat.marked
Estimating parameters
To estimate the model parameters, we rely on the code below
library('jagsUI')
# MCMC settings
<- 10000 #number of iterations
ni <- 5 #interval to thin
nt <- 5000 #number of iterations to discard as burn-in
nb <- 3 #number of chains
nc
#parameters to monitor
=c('lambda0','sig2','psi','coord.acenter','w')
params
#number of potential individuals
=100
ntilde
#data for jags
=list(zmat=zmat.marked,coord.trap=coord.traps,
dat1nind.marked=nind.marked,ntimes=ntimes,ntraps=ntraps,
nvec=nvec.unmarked,ntilde=ntilde)
#run JAGS
=function(){
initslist(w=rep(1,ntilde))
}
setwd('U:\\uf\\courses\\bayesian course\\group activities\\17 example scr\\mod4')
=jags(model.file="marked unmarked unknown N JAGS.R",inits=inits,
model4parameters.to.save=params,data=dat1,
n.chains=nc,n.burnin=nb,n.iter=ni,n.thin=nt,DIC=TRUE)
summary(model4) #the Rhat results suggest that the algorithm has converged
#look at model parameters
plot(model4$sims.list$lambda0,type='l',ylab='lambda0',xlab='Iterations')
abline(h=10,col='red')
plot(model4$sims.list$sig2,type='l',ylab='sigma2',xlab='Iterations')
abline(h=5,col='red')
As expected, we can estimate \(\lambda_0\) and \(\sigma^2\). However, we can also estimate well population size N:
plot(model4$sims.list$psi*ntilde,type='l',ylab='Nhat',xlab='Iterations')
abline(h=20,col='red')
Finally, given that the name of this model is spatial capture-recapture, let’s see how well we can estimate the spatial distribution of these individuals. To calculate this, I will use the following steps for each posterior sample:
Get the estimated coordinates of the activity centers, just for the individuals estimated to truly exist
Use a 2D kernel estimate to calculate the 2D density.
Store these results.
Here is the code that I use to make this comparison.
library('MASS')
library('ggplot2')
=model4$sims.list$coord.acenter
coord.estim=model4$sims.list$w
w.estim=nrow(coord.estim)
npost
=matrix(NA,npost,51*51)
resfor (i in 1:npost){
#get coordinates just for individuals that exist
=w.estim[i,]
w=coord.estim[i,,]
coord=which(w==1)
ind=coord[ind,]
coord1=data.frame(x=coord1[,1],y=coord1[,2])
coord2
#2d kernel
<- kde2d(coord2$x, coord2$y, n = 51,
f1 lims=c(0,100,0,100)); #image(f1)
=data.frame(x=rep(f1$x,51),
f2y=rep(f1$y,each=51),
z=matrix(f1$z,51*51,1))
=f2$z
res[i,]
}
#calculate posterior mean of 2D density
=data.frame(x=f2$x,y=f2$y,
res1z=colMeans(res))
=max(res1$z)
max1
ggplot(data=res1,aes(x=x,y=y,fill=z))+
geom_tile()+
theme(legend.position="none")+
scale_fill_gradient2(low = "cyan", mid = "red",high='purple',
limits=c(0,max1),midpoint=0.5*max1)
Let’s compare these results to the true 2D density.
#compare to true density
<- kde2d(coord.acenter$x, coord.acenter$y, n = 51,
f1 lims=c(0,100,0,100)); #image(f1)
=data.frame(x=rep(f1$x,51),
f2y=rep(f1$y,each=51),
z=matrix(f1$z,51*51,1))
=max(f2$z)
max1ggplot(data=f2,aes(x=x,y=y,fill=z))+
geom_tile()+
theme(legend.position="none")+
scale_fill_gradient2(low = "cyan", mid = "red",high='purple',
limits=c(0,max1),midpoint=0.5*max1)
Comments?
Send me an email at