‘postpack’ ships with two example mcmc.list
objects to
allow self-contained examples and for users to practice using
‘postpack’. The mcmc.list
objects can be loaded using:
Both objects come from a JAGS model fitted to simulated data. The two objects are from two separate, but highly similar models. The output was thinned heavily to reduce file size, see:
postpack::post_dim(cjs)
## burn post_burn thin chains saved params
## 11000 50000 200 2 500 21
Each of two chains was ran for 61,000 iterations – 11,000 were adapting/burn-in phase and 50,000 were after burn-in. Chains were thinned at an interval of 200 iterations, resulting in 500 total saved samples per 21 parameters (elements in the model).
Posterior samples were generated from a model fitted to a hypothetical (i.e., simulated) data set. Suppose for 5 years, biologists individually tagged juvenile salmon in the headwaters of a river system before the fish made their migration out to sea. The length of each fish was measured as well, and it is safe to assume tagged fish are a random sample from the larger population and that they were all released at the same time within a given year.
Three receiver arrays exist in the river that can detect fish as they move past them, but they are imperfect (sometimes a receiver will not detect a tagged fish passing it). The principle research goal is to quantify whether survival during migration is associated with fish size.
Known quantities necessary for fitting the model (see below) include:
nt
: number of yearsyear
: year indicator variableJ
: number of times each fish can be detected, including
tagging eventN
: number of fish tagged in the study (across all
years)y
: detection history matrix (N
by
J
); 1 if fish seen that event, 0 if not.The model is a Cormack-Jolly-Seber survival model. It estimates survival and detection probabilities based on individually-identifiable tagged fish. Based on how often a fish is not seen at a location and then seen at a later location, it is possible to estimate detection probabilities. Then, based on how often a fish is never seen again, it is possible to estimate survival probabilities1.
This is a state-space formulation, where there are explicit random
processes for both the true state of each fish (alive or dead) and the
observed state of each fish (detected or not detected) in each event.
Both are Bernoulli random variables, with z
representing
the true state (0 = dead; 1 = alive) and y
representing the
observed state (0 = not detected; 1 = detected). It is assumed that fish
cannot be detected if they are dead. Survival probability between two
consecutive detection events for fish i
is denoted by
phi[i]
and for this model is expressed as a logit-linear
function of fish size (FL[i]
, scaled and centered prior to
model fitting), with random slopes and intercepts for each year.
Detection probability for this model is assumed to vary among detection
arrays, but is constant across years for a given array.
Here is the JAGS code for this model:
model{
# HYPERPARAMETERS: SURVIVAL COEFFICIENTS AND VARIABILITY
B0 ~ dnorm(0, 0.001)
B1 ~ dnorm(0, 0.001)
sig_B0 ~ dunif(0,10)
sig_B1 ~ dunif(0,10)
rho ~ dunif(-1,1)
# COVARIANCE MATRIX FOR YEAR-SPECIFIC SURVIVAL COEFFICIENTS
SIG[1,1] <- sig_B0^2
SIG[2,2] <- sig_B1^2
SIG[2,1] <- sig_B0 * sig_B1 * rho
SIG[1,2] <- sig_B0 * sig_B1 * rho
# YEAR-SPECIFIC SURVIVAL COEFFICIENTS
Bmean[1] <- B0
Bmean[2] <- B1
for (t in 1:nt) {
b[t,1:2] ~ dmnorm.vcov(Bmean[1:2], SIG[1:2,1:2])
b0[t] <- b[t,1]
b1[t] <- b[t,2]
}
# DETECTION PROBABILITY: OCCASION-SPECIFIC, BUT YEAR-CONSTANT
for (j in 2:J) {
p[j] ~ dunif(0,1)
}
# LIKELIHOOD
for (i in 1:N) {
# obtain fish-specific survival based on size
logit(phi[i]) <- b0[year[i]] + b1[year[i]] * FL[i]
for (j in 2:J) {
# latent survival process:
# must have been alive last period to be alive this period
z[i,j] ~ dbern(z[i,j-1] * phi[i])
# observation process:
# must be alive this period to be detected this period
y[i,j] ~ dbern(z[i,j] * p[j])
}
}
}
Parameter definitions:
B0
: intercept of logit-linear survival vs. length
relationship: global mean across yearsB1
: slope of logit-linear survival v. length
relationship: global mean across yearsb0[1:5]
: year-specific survival random interceptsb1[1:5]
: year-specific survival random slopessig_B0
: standard deviation of year-specific
interceptssig_B1
: standard deviation of year-specific slopesrho
: correlation between random intercepts and
slopesSIG[1:2,1:2]
: variance-covariance matrix modeling the
covariance between random slopes and interceptsp[2:4]
: detection probability for each receiver array,
assumed constant across years (note the first detection occasion is not
modeled because that is the tagging event – all fish were alive and
detected)The mcmc.list
object accessed via data(cjs)
is from this model exactly, the one found in
data(cjs_no_rho)
is from the same model, but with the
rho
parameter fixed at zero rather than estimating its
value.
The nodes that were monitored include:
postpack::get_params(cjs, type = "base_index")
## [1] "B0" "sig_B0" "B1" "sig_B1" "b0[1]" "b0[2]"
## [7] "b0[3]" "b0[4]" "b0[5]" "b1[1]" "b1[2]" "b1[3]"
## [13] "b1[4]" "b1[5]" "SIG[1,1]" "SIG[2,1]" "SIG[1,2]" "SIG[2,2]"
## [19] "p[2]" "p[3]" "p[4]"
Readers interested in this kind of model are encouraged to refer to Bayesian Population Analysis using WinBUGS: A Hierarchical Perspective by Marc Kéry and Michael Schuab.↩︎