Introduction

In this example, we will be working with a model called spatial capture-recapture (SCR) which was originally described in Chandler and Royle (2013). This is a really cool model because it allows us to estimate population size and its spatial distribution. For this model to work, we assume that we have an array of traps (e.g., camera traps or anything capable of recording counts of unmarked and marked individuals) that are sufficiently close that individual animals might be encountered at multiple locations.

To understand how this model works, it is important to start with simpler version of it to then slowly build up complexity. More specifically, we will describe the following sequence of models:

  1. A model in which all the individuals are marked. The goal here is to introduce the main parameters that govern the SCR model.

  2. A model in which all the individuals are unmarked but the number of individuals is assumed to be known. The goal here is to show that, in the absence of marked individuals, it is hard to make this model converge.

  3. A model in which some individuals are marked but some are unmarked. In this model, the total number of individuals is still assumed to be known. We show that the presence of marked individual can solve the problem that we were facing with (2).

  4. A model in which some individuals are marked but some are unmarked. However, differently from (3), the total number of individuals is estimated. This is the SCR model.

Model 1: all marked individuals

We assume that each animal is counted at \(J\) traps on \(K\) occasions. As a result, for each animal, we end up with a \(J \times K\) matrix of counts. Let \(z_{ijk}\) be a non-negative integer describing the number of times individual \(i\) was seen in trap \(j\) and occasion \(k\). We assume that:

\[z_{ijk} \sim Poisson (\lambda_{ij})\] We assume that the expected number of captures \(\lambda_{ij}\) depends on how close trap \(j\) is to the activity center of animal \(i\). If it is very close, then we expected higher counts whereas, if it is very far, we expect lower counts. To represent this pattern, we rely on a half-normal, given by:

\[\lambda_{ij} = \lambda_0 exp(-d_{ij}/\sigma^2)\]

where \(d_{ij}\) is the distance between activity center for animal \(i\) and trap \(j\) and \(\lambda_0\) is the expected count when distance is zero. In this model, \(\sigma^2\) governs how fast the expected count decreases with distance. It is important to mention that the original model in Chandler and Royle (2013) had a slightly different formulation, where \(\lambda_{ij} = \lambda_0 exp(-\frac{d_{ij}^2}{2\sigma^2})\). I prefer the formulation above because it is simpler.

Here is an illustration of these ideas, assuming that \(\lambda_0=8\) and \(\sigma^2=10\).

rm(list=ls())

#trap coordinates
coord.traps=expand.grid(x=1:3,y=1:3)
par(mfrow=c(1,2),mar=c(4,4,3,1))
plot(y~x,data=coord.traps,xlim=c(0.5,3.5),ylim=c(0.5,3.5),
     main='Spatial distrib. traps and centers')
text(y~x,data=coord.traps,1:9,col='grey',pos=1)

#activity center coordinates
act.center=data.frame(x=2.7,y=2.1)
points(y~x,data=act.center,col='red',pch=19)

#parameter values
lambda0=8
sigma2=10

#calculate expected counts
dist1=seq(from=0,to=2,length.out=100)
exp.count=lambda0*exp(-dist1/sigma2)
plot(dist1,exp.count,type='l',ylab='Expected count',xlab='Distance',ylim=c(0,lambda0),
     main='Relation exp. counts and dist.')

#calculate distance to trap locations
x2=(act.center$x-coord.traps$x)^2
y2=(act.center$y-coord.traps$y)^2
dist1=sqrt(x2+y2)

#calculate expected counts for each trap
exp.count=lambda0*exp(-dist1/sigma2)
points(dist1,exp.count)
text(dist1,exp.count,1:9,col='grey',pos=1)

In these figures, the numbers in grey are the trap ids and the solid red circle is the activity center.

Model 1: simulated data

Here is how we simulate some data based on this set-up.

rm(list=ls())
# library('proxy')
library('ggplot2')
set.seed(1)

#parameter values
sig2=10
lambda0=8

#number of marked individuals
nind=3

#spatial extent
xmax=ymax=100

#coordinates of activity center
coord.acenter=data.frame(x=runif(nind,min=0,max=xmax),
                         y=runif(nind,min=0,max=ymax))

#traps and their coordinates
ntraps=25 #number of traps
tmp=seq(from=1,to=xmax,length.out=5)
coord.traps=expand.grid(x=tmp,
                        y=tmp)

#encounter times
ntimes=5 

#calculate distances
dist1=matrix(NA,ntraps,nind)
for (j in 1:ntraps){
  for (i in 1:nind){
    x2=(coord.traps$x[j]-coord.acenter$x[i])^2
    y2=(coord.traps$y[j]-coord.acenter$y[i])^2
    dist1[j,i]=sqrt(x2+y2)
  }
}
# dist1a=proxy::dist(x=coord.traps,y=coord.acenter)
# unique(dist1-dist1a)

#generate z
n=matrix(NA,ntraps,ntimes)
zarray=array(NA,dim=c(nind,ntraps,ntimes))
for (t1 in 1:ntimes){
  z=matrix(NA,ntraps,nind)
  for (i in 1:nind){
    g=exp(-dist1[,i]/sig2)    
    z[,i]=rpois(ntraps,lambda0*g)
    zarray[i,,t1]=z[,i]
  }
  n[,t1]=apply(z,1,sum)
}

#sum over time steps
N=apply(n,1,sum)
coord.traps$N=N
ggplot()+
  geom_tile(data=coord.traps,aes(x=x,y=y,fill=N))+
  geom_point(data=coord.acenter,aes(x=x,y=y),col='red')

#export data
setwd('U:\\uf\\courses\\bayesian course\\group activities\\17 example scr\\mod1')
write.csv(coord.traps[,-3],'coord traps.csv',row.names=F)
write.csv(coord.acenter,'coord acenter.csv',row.names=F)
zarray1=matrix(zarray,nind*ntraps*ntimes,1)
write.csv(zarray1,'zarray.csv',row.names=F)

This figure shows that, as expected, the traps with higher counts (lighter blue colors) are those that are closer to the activity centers (red circles).



Comments?

Send me an email at

References

Chandler, R. B., and J. A. Royle. 2013. “Spatially Explicit Models for Inference about Density in Unmarked or Partially Marked Populations.” The Annals of Applied Statistics 7: 936–54.