unmarked
How to estimate abundance without marking animals?
In an occupancy model:
Replace detection with counts and occupancy with abundance:
This is the N-mixture model of Royle (2004)
Parameters
$N_i$: Latent abundance at site $i$
$\lambda_i$: Expected abundance at site $i$
Math
$$N_i \sim \mathrm{Poisson}(\lambda_i)$$You could also use other distributions, such as:
Parameters/data
$y_{ij}$: Observed count at site $i$ for repeated sample $j$
$p_{ij}$: Probability of detecting an individual at site $i$ in sample $j$
Math
$$y_{ij} \sim \mathrm{Binomial}(p_{ij}, N_i)$$library(unmarked)
data(mallard)
head(mallard.y)
y.1 | y.2 | y.3 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 0 |
3 | 2 | 1 |
0 | 0 | 0 |
3 | 0 | 3 |
0 | 0 | 0 |
jags_data <- list(y = mallard.y, M = 239, J = 3)
Math
$$N_i \sim \mathrm{Poisson}(\lambda)$$Code
for (i in 1:M){
N[i] ~ dpois(lambda)
}
lambda ~ dunif(0, 100) # prior should be positive
Math
$$y_{ij} \sim \mathrm{Binomial}(p,N_i)$$Code
for (i in 1:M){
for (j in 1:J){
y[i,j] ~ dbinom(p, N[i])
}
}
p ~ dunif(0,1) # prior must be between 0 and 1
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(lambda)
}
lambda ~ dunif(0, 100)
# Detection model
for (i in 1:M){
for (j in 1:J){
y[i,j] ~ dbinom(p, N[i])
}
}
p ~ dunif(0,1)
sumN <- sum(N[])
}
", file = "nmixture_null.bugs")
pars <- c("lambda", "p", "sumN")
# initialize z at maximum count ever observed at a site
Ninit <- apply(mallard.y, 1, max, na.rm=TRUE)
Ninit[is.infinite(Ninit)] <- NA
Ninit
inits <- function() list(N = Ninit)
Warning message in FUN(newX[, i], ...): “no non-missing arguments to max; returning -Inf” Warning message in FUN(newX[, i], ...): “no non-missing arguments to max; returning -Inf” Warning message in FUN(newX[, i], ...): “no non-missing arguments to max; returning -Inf” Warning message in FUN(newX[, i], ...): “no non-missing arguments to max; returning -Inf”
library(jagsUI)
jags_null <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_null.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jagsUI::traceplot(jags_null)
jags_null
JAGS output for model 'nmixture_null.bugs', generated by jagsUI. Estimates based on 3 chains of 10000 iterations, adaptation = 100 iterations (sufficient), burn-in = 8000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 0.129 minutes at time 2023-07-19 12:21:33.799883. mean sd 2.5% 50% 97.5% overlap0 f Rhat n.eff lambda 0.352 0.041 0.276 0.350 0.437 FALSE 1 1.000 6000 p 0.645 0.038 0.567 0.646 0.719 FALSE 1 1.001 2621 sumN 83.176 3.641 77.000 83.000 91.000 FALSE 1 1.002 1170 deviance 261.189 14.429 237.703 259.782 292.910 FALSE 1 1.003 1196 Successful convergence based on Rhat values (all < 1.1). Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 104 and DIC = 365.142 DIC is an estimate of expected predictive error (lower is better).
Including the site-level covariates
head(mallard.site)
# already standardized?
round(colMeans(mallard.site), 2)
round(apply(mallard.site, 2, sd), 2)
elev | length | forest | |
---|---|---|---|
<dbl> | <dbl> | <dbl> | |
1 | -1.173 | 0.801 | -1.156 |
2 | -1.127 | 0.115 | -0.501 |
3 | -0.198 | -0.479 | -0.101 |
4 | -0.105 | 0.315 | 0.008 |
5 | -1.034 | -1.102 | -1.193 |
6 | -0.848 | 0.741 | 0.917 |
jags_data <- list(y = mallard.y, M = 239, J = 3,
elev = mallard.site$elev, forest = mallard.site$forest)
str(jags_data)
List of 5 $ y : num [1:239, 1:3] 0 0 3 0 3 0 0 0 0 0 ... ..- attr(*, "dimnames")=List of 2 .. ..$ : NULL .. ..$ : chr [1:3] "y.1" "y.2" "y.3" $ M : num 239 $ J : num 3 $ elev : num [1:239] -1.173 -1.127 -0.198 -0.105 -1.034 ... $ forest: num [1:239] -1.156 -0.501 -0.101 0.008 -1.193 ...
Math
$$N_i \sim \mathrm{Poisson}(\lambda_i)$$$$\mathrm{log}(\lambda_i) = \beta_0 + \beta_{ele} \cdot \mathrm{elev}_i + \beta_{for} \cdot \mathrm{forest}_i$$Code
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
# Detection model
for (i in 1:M){
for (j in 1:J){
y[i,j] ~ dbinom(p, N[i])
}
}
p ~ dunif(0,1)
sumN <- sum(N[])
}
", file = "nmixture_covs.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "p", "sumN")
inits <- function() list(N = Ninit)
library(jagsUI)
jags_covs <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_covs.bugs",
n.chains = 3, n.iter = 20000, n.burnin = 18000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jagsUI::traceplot(jags_covs)
jags_covs
JAGS output for model 'nmixture_covs.bugs', generated by jagsUI. Estimates based on 3 chains of 20000 iterations, adaptation = 100 iterations (sufficient), burn-in = 18000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 0.384 minutes at time 2023-07-19 12:21:42.594846. mean sd 2.5% 50% 97.5% overlap0 f Rhat n.eff beta_0 -2.322 0.278 -2.943 -2.299 -1.829 FALSE 1 1.236 13 beta_ele -1.615 0.255 -2.187 -1.608 -1.146 FALSE 1 1.357 10 beta_for -0.951 0.155 -1.246 -0.954 -0.657 FALSE 1 1.008 298 p 0.613 0.045 0.521 0.616 0.696 FALSE 1 1.001 1503 sumN 88.908 5.396 80.000 88.000 102.000 FALSE 1 1.001 1482 deviance 259.127 14.175 236.036 257.557 290.180 FALSE 1 1.000 6000 **WARNING** Rhat values indicate convergence failure. Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 100.5 and DIC = 359.609 DIC is an estimate of expected predictive error (lower is better).
In each MCMC iteration:
fit
(Pearson's $\chi^2$) on the real datafit_new
for the new datasetAfter the run:
fit < fit_new
= Bayesian p-valueMath
$$\hat{y}_{ij} = N_i \cdot p $$$$\mathrm{fit}_{\chi^2} = \sum{\frac{(y_{ij} - \hat{y}_{ij})^2}{\hat{y}_{ij}}}$$Code
# real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] = N[i] * p
chi2[i,j] = (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit = sum(chi2)
Simulate new dataset
$$y^{new}_{ij} \sim \mathrm{Binomial}(p, N_i)$$Calculate fit for new dataset
$$\hat{y}_{ij} = N_i \cdot p $$$$\mathrm{fit}^{new}_{\chi^2} = \sum{\frac{(y^{new}_{ij} - \hat{y}_{ij})^2}{\hat{y}_{ij}}}$$Code
# simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p, N[i]) # simulate new datapoint
yhat[i,j] = N[i] * p
chi2_new[i,j] = (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new = sum(chi2_new)
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
# Detection model
for (i in 1:M){
for (j in 1:J){
y[i,j] ~ dbinom(p, N[i])
}
}
p ~ dbeta(1,1)
# Fit statistic for real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] = N[i] * p + 0.001 # add small value to avoid divide by zero
chi2[i,j] = (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit = sum(chi2)
# Fit statistic for simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p, N[i]) # simulate new datapoint
chi2_new[i,j] = (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new = sum(chi2_new)
sumN <- sum(N[])
}
", file = "nmixture_covs.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "p", "fit", "fit_new", "sumN")
inits <- function() list(N = Ninit)
library(jagsUI)
jags_covs <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_covs.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
Bayesian p-value
mean(jags_covs$sims.list$fit < jags_covs$sims.list$fit_new)
Posterior predictive check plot
Plot fit
vs. fit_new
.
A line with intercept 0 and slope 1 should approximately bisect the point cloud.
plot(jags_covs$sims.list$fit, jags_covs$sims.list$fit_new)
abline(a=0, b=1)
pp.check(jags_covs, "fit","fit_new")
Based on this test, the model appears to fit the data poorly.
Potential solutions:
More research should be done in this area to develop better GoF tests.
Use JAGS to fit the following model.
mallard.obs
)Note there are missing values in the observation covariate ivel
! See the dynamic occupancy model code for one way to handle this in JAGS. Hint: you can model the missing values of ivel
.
Don't forget: p
now becomes indexed by i
and j
Check goodness-of-fit.
head(mallard.obs$ivel)
dim(mallard.obs$ivel)
ivel.1 | ivel.2 | ivel.3 |
---|---|---|
-0.506 | -0.506 | -0.506 |
-0.934 | -0.991 | -1.162 |
-1.136 | -1.339 | -1.610 |
-0.819 | -0.927 | -1.197 |
0.638 | 0.880 | 1.042 |
-1.329 | -1.042 | -0.899 |
jags_data <- list(y = mallard.y, M = 239, J = 3,
elev = mallard.site$elev, forest = mallard.site$forest,
ivel = mallard.obs$ivel)
str(jags_data)
List of 6 $ y : num [1:239, 1:3] 0 0 3 0 3 0 0 0 0 0 ... ..- attr(*, "dimnames")=List of 2 .. ..$ : NULL .. ..$ : chr [1:3] "y.1" "y.2" "y.3" $ M : num 239 $ J : num 3 $ elev : num [1:239] -1.173 -1.127 -0.198 -0.105 -1.034 ... $ forest: num [1:239] -1.156 -0.501 -0.101 0.008 -1.193 ... $ ivel : num [1:239, 1:3] -0.506 -0.934 -1.136 -0.819 0.638 ... ..- attr(*, "dimnames")=List of 2 .. ..$ : NULL .. ..$ : chr [1:3] "ivel.1" "ivel.2" "ivel.3"
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01)
# Model missing values in ivel
for (i in 1:M){
for (j in 1:J){
ivel[i,j] ~ dnorm(ivel_mean, ivel_tau)
}
}
ivel_mean ~ dnorm(0, 0.01)
ivel_tau <- pow(ivel_sd, -2)
ivel_sd ~ dunif(0, 10)
# Detection model
for (i in 1:M){
for (j in 1:J){
logit(p[i,j]) <- alpha_0 + alpha_ivel * ivel[i,j]
y[i,j] ~ dbinom(p[i,j], N[i])
}
}
alpha_0 ~ dlogis(0, 1)
alpha_ivel ~ dlogis(0, 1)
# Fit statistic for real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] <- N[i] * p[i,j] + 0.001 # add small value to avoid divide by zero
chi2[i,j] <- (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit <- sum(chi2)
# Fit statistic for simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p[i,j], N[i]) # simulate new datapoint
chi2_new[i,j] <- (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new <- sum(chi2_new)
sumN <- sum(N[])
}
", file = "nmixture_obscovs.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "beta_ele2", "alpha_0", "alpha_ivel", "fit", "fit_new", "sumN")
inits <- function() list(N = Ninit)
library(jagsUI)
jags_covs2 <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_obscovs.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jags_covs2
jagsUI::traceplot(jags_covs2)
JAGS output for model 'nmixture_obscovs.bugs', generated by jagsUI. Estimates based on 3 chains of 10000 iterations, adaptation = 100 iterations (sufficient), burn-in = 8000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 0.715 minutes at time 2023-07-19 12:22:21.342982. mean sd 2.5% 50% 97.5% overlap0 f Rhat beta_0 -1.916 0.292 -2.500 -1.913 -1.359 FALSE 1.000 1.017 beta_ele -1.438 0.245 -1.983 -1.420 -1.014 FALSE 1.000 1.005 beta_for -0.761 0.180 -1.131 -0.753 -0.424 FALSE 1.000 1.001 beta_ele2 -0.056 0.263 -0.595 -0.036 0.438 TRUE 0.555 1.013 alpha_0 0.402 0.219 -0.040 0.405 0.818 TRUE 0.963 1.003 alpha_ivel 0.439 0.171 0.109 0.442 0.770 FALSE 0.996 1.002 fit 78.023 12.696 59.058 76.216 109.082 FALSE 1.000 1.004 fit_new 65.582 13.616 43.622 63.966 97.240 FALSE 1.000 1.005 sumN 95.117 8.808 82.000 94.000 116.000 FALSE 1.000 1.008 deviance 2159.504 18.342 2128.796 2158.085 2200.556 FALSE 1.000 1.006 n.eff beta_0 132 beta_ele 6000 beta_for 2215 beta_ele2 157 alpha_0 672 alpha_ivel 1117 fit 906 fit_new 800 sumN 401 deviance 491 Successful convergence based on Rhat values (all < 1.1). Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 167.6 and DIC = 2327.08 DIC is an estimate of expected predictive error (lower is better).
pp.check(jags_covs2, 'fit', 'fit_new')
Math
$$N_i \sim \mathrm{NegativeBinomial}(\lambda_i, \phi)$$$$\mathrm{log}(\lambda_i) = \beta_0 + \beta_{ele} \cdot \mathrm{elev}_i + \beta_{for} \cdot \mathrm{forest}_i$$$\phi$ is the dispersion parameter, as $\phi$ gets small NB converges with Poisson
Code
JAGS parameterizes the negative binomial in the success/failure way:
dnegbin(p, r)
We'll call the p
parameter s
(for success) since we will use p
for detection.
N[i] ~ dnegbin(s[i], r)
We need to convert between our parameterization ($\lambda$) and the JAGS way ($s$)
$$s_i = \frac{r}{r+\lambda_i}$$$$\phi =\frac{1}{r}$$for (i in 1:M){
N[i] ~ dnegbin(s[i], r)
s[i] <- r / (r + lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i]
}
r ~ dunif(0, 50)
phi <- 1/r
# other priors
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dnegbin(s[i], r)
s[i] <- r / (r + lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i]
}
r ~ dunif(0, 50)
phi <- 1/r
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01)
# Model missing values in ivel
for (i in 1:M){
for (j in 1:J){
ivel[i,j] ~ dnorm(ivel_mean, ivel_tau)
}
}
ivel_mean ~ dnorm(0, 0.01)
ivel_tau <- pow(ivel_sd, -2)
ivel_sd ~ dunif(0, 10)
# Detection model
for (i in 1:M){
for (j in 1:J){
logit(p[i,j]) <- alpha_0 + alpha_ivel * ivel[i,j]
y[i,j] ~ dbinom(p[i,j], N[i])
}
}
alpha_0 ~ dunif(-10,10)
alpha_ivel ~ dnorm(0, 0.01)
# Fit statistic for real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] <- N[i] * p[i,j] + 0.001 # add small value to avoid divide by zero
chi2[i,j] <- (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit <- sum(chi2)
# Fit statistic for simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p[i,j], N[i]) # simulate new datapoint
chi2_new[i,j] <- (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new <- sum(chi2_new)
sumN <- sum(N[])
}
", file = "nmixture_nb.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "beta_ele2", "alpha_0", "alpha_ivel", "phi", "fit", "fit_new", "sumN")
inits <- function() list(N = Ninit)
library(jagsUI)
jags_nb <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_nb.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jagsUI::traceplot(jags_nb)
jags_nb
JAGS output for model 'nmixture_nb.bugs', generated by jagsUI. Estimates based on 3 chains of 10000 iterations, adaptation = 100 iterations (sufficient), burn-in = 8000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 1.011 minutes at time 2023-07-19 12:23:05.539394. mean sd 2.5% 50% 97.5% overlap0 f Rhat beta_0 -1.803 0.396 -2.598 -1.795 -1.034 FALSE 1.000 1.007 beta_ele -1.506 0.290 -2.130 -1.488 -0.987 FALSE 1.000 1.005 beta_for -0.714 0.230 -1.171 -0.710 -0.279 FALSE 0.999 1.002 beta_ele2 0.031 0.335 -0.661 0.045 0.655 TRUE 0.553 1.008 alpha_0 -0.092 0.339 -0.824 -0.060 0.497 TRUE 0.578 1.011 alpha_ivel 0.238 0.205 -0.158 0.235 0.645 TRUE 0.881 1.002 phi 2.443 0.830 1.144 2.330 4.368 FALSE 1.000 1.000 fit 81.230 14.435 59.833 78.802 115.121 FALSE 1.000 1.014 fit_new 76.655 17.303 50.357 74.109 117.080 FALSE 1.000 1.012 sumN 119.791 23.745 89.975 114.000 179.025 FALSE 1.000 1.027 deviance 2156.426 16.525 2127.885 2155.039 2192.254 FALSE 1.000 1.009 n.eff beta_0 295 beta_ele 534 beta_for 1503 beta_ele2 364 alpha_0 228 alpha_ivel 1724 phi 5753 fit 232 fit_new 236 sumN 163 deviance 274 Successful convergence based on Rhat values (all < 1.1). Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 135.6 and DIC = 2292.008 DIC is an estimate of expected predictive error (lower is better).
pp.check(jags_nb, "fit","fit_new")
Useful when there are more 0s in the dataset than you would expect from just the Poisson
Math
$$N_i \sim \mathrm{Poisson}(w_i \cdot \lambda_i)$$$$w_i \sim \mathrm{Bernoulli}(1-\psi)$$$$\mathrm{log}(\lambda_i) = \beta_0 + \beta_{ele} \cdot \mathrm{elev}_i + \beta_{for} \cdot \mathrm{forest}_i$$$\psi$ is the zero-inflation parameter (~ % of samples that are forced 0s)
In ecology we could think of this distribution like so:
Code
for (i in 1:M){
N[i] ~ dpois(w[i] * lambda[i])
w[i] ~ dbern(1-psi)
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01
psi ~ dunif(0, 1)
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(w[i]*lambda[i])
w[i] ~ dbern(1-psi)
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01)
psi ~ dunif(0, 1)
# Model missing values in ivel
for (i in 1:M){
for (j in 1:J){
ivel[i,j] ~ dnorm(ivel_mean, ivel_tau)
}
}
ivel_mean ~ dnorm(0, 0.01)
ivel_tau <- pow(ivel_sd, -2)
ivel_sd ~ dunif(0, 10)
# Detection model
for (i in 1:M){
for (j in 1:J){
logit(p[i,j]) <- alpha_0 + alpha_ivel * ivel[i,j]
y[i,j] ~ dbinom(p[i,j], N[i])
}
}
alpha_0 ~ dunif(-10,10)
alpha_ivel ~ dnorm(0, 0.01)
# Fit statistic for real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] <- N[i] * p[i,j] + 0.001 # add small value to avoid divide by zero
chi2[i,j] <- (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit <- sum(chi2)
# Fit statistic for simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p[i,j], N[i]) # simulate new datapoint
chi2_new[i,j] <- (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new <- sum(chi2_new)
sumN <- sum(N[])
}
", file = "nmixture_zip.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "beta_ele2", "alpha_0", "alpha_ivel", "psi", "fit", "fit_new", "sumN")
inits <- function() list(N = Ninit, psi = 0)
library(jagsUI)
jags_zip <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_zip.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jagsUI::traceplot(jags_zip)
jags_zip
JAGS output for model 'nmixture_zip.bugs', generated by jagsUI. Estimates based on 3 chains of 10000 iterations, adaptation = 100 iterations (sufficient), burn-in = 8000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 0.792 minutes at time 2023-07-19 12:24:07.475039. mean sd 2.5% 50% 97.5% overlap0 f Rhat beta_0 -0.949 0.406 -1.708 -0.954 -0.138 FALSE 0.991 1.031 beta_ele -1.408 0.264 -1.982 -1.393 -0.940 FALSE 1.000 1.003 beta_for -0.578 0.201 -0.980 -0.580 -0.185 FALSE 0.999 1.022 beta_ele2 -0.093 0.273 -0.630 -0.089 0.436 TRUE 0.637 1.012 alpha_0 0.074 0.312 -0.614 0.104 0.619 TRUE 0.637 1.023 alpha_ivel 0.466 0.171 0.135 0.466 0.797 FALSE 0.997 1.002 psi 0.516 0.084 0.342 0.520 0.670 FALSE 1.000 1.037 fit 80.059 14.109 59.963 77.609 114.254 FALSE 1.000 1.011 fit_new 72.203 15.328 48.180 69.978 108.101 FALSE 1.000 1.014 sumN 112.540 20.396 87.000 108.000 166.025 FALSE 1.000 1.025 deviance 2162.634 17.492 2133.511 2160.811 2201.165 FALSE 1.000 1.014 n.eff beta_0 75 beta_ele 1099 beta_for 102 beta_ele2 207 alpha_0 98 alpha_ivel 1036 psi 60 fit 220 fit_new 160 sumN 111 deviance 164 Successful convergence based on Rhat values (all < 1.1). Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 151.2 and DIC = 2313.801 DIC is an estimate of expected predictive error (lower is better).
pp.check(jags_zip, "fit","fit_new")
(also called Poisson-lognormal model)
Math
$$N_i \sim \mathrm{Poisson}(\lambda_i)$$$$\mathrm{log}(\lambda_i) = \beta_0 + \beta_{ele} \cdot \mathrm{elev}_i + \beta_{for} \cdot \mathrm{forest}_i + \epsilon_i$$$$\epsilon_i \sim \mathrm{Normal}(0, \sigma^2)$$Code
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i] + eps[i]
eps[i] ~ dnorm(0, tau)
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01)
tau <- pow(sigma, -2)
sigma ~ dunif(0, 10)
cat("
model{
# State model
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i] +
beta_ele2 * elev[i] * elev[i] + eps[i]
eps[i] ~ dnorm(0, tau)
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
beta_ele2 ~ dnorm(0, 0.01)
tau <- pow(sigma, -2)
sigma ~ dunif(0, 10)
# Model missing values in ivel
for (i in 1:M){
for (j in 1:J){
ivel[i,j] ~ dnorm(ivel_mean, ivel_tau)
}
}
ivel_mean ~ dnorm(0, 0.01)
ivel_tau <- pow(ivel_sd, -2)
ivel_sd ~ dunif(0, 10)
# Detection model
for (i in 1:M){
for (j in 1:J){
logit(p[i,j]) <- alpha_0 + alpha_ivel * ivel[i,j]
y[i,j] ~ dbinom(p[i,j], N[i])
}
}
alpha_0 ~ dunif(-10,10)
alpha_ivel ~ dnorm(0, 0.01)
# Fit statistic for real data
for (i in 1:M){
for (j in 1:J){
yhat[i,j] <- N[i] * p[i,j] + 0.001 # add small value to avoid divide by zero
chi2[i,j] <- (y[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit <- sum(chi2)
# Fit statistic for simulated data
for (i in 1:M){
for (j in 1:J){
y_new[i,j] ~ dbinom(p[i,j], N[i]) # simulate new datapoint
chi2_new[i,j] <- (y_new[i,j] - yhat[i,j])^2 / yhat[i,j]
}
}
fit_new <- sum(chi2_new)
sumN <- sum(N[])
}
", file = "nmixture_pln.bugs")
pars <- c("beta_0", "beta_ele", "beta_for", "beta_ele2", "alpha_0", "alpha_ivel", "sigma", "fit", "fit_new", "sumN")
inits <- function() list(N = Ninit, psi = 0)
library(jagsUI)
jags_pln <- jags(data = jags_data,
inits = inits,
parameters.to.save = pars,
model.file = "nmixture_pln.bugs",
n.chains = 3, n.iter = 10000, n.burnin = 8000,
parallel=TRUE)
Processing function input....... Done. Beginning parallel processing using 3 cores. Console output will be suppressed. Parallel processing completed. Calculating statistics....... Done.
jagsUI::traceplot(jags_pln)
jags_pln
JAGS output for model 'nmixture_pln.bugs', generated by jagsUI. Estimates based on 3 chains of 10000 iterations, adaptation = 100 iterations (sufficient), burn-in = 8000 iterations and thin rate = 1, yielding 6000 total samples from the joint posterior. MCMC ran in parallel for 0.811 minutes at time 2023-07-19 12:24:56.146931. mean sd 2.5% 50% 97.5% overlap0 f Rhat beta_0 -3.140 0.551 -4.292 -3.122 -2.191 FALSE 1.000 1.023 beta_ele -1.623 0.309 -2.252 -1.613 -1.048 FALSE 1.000 1.028 beta_for -0.755 0.281 -1.352 -0.736 -0.247 FALSE 0.998 1.007 beta_ele2 0.197 0.363 -0.489 0.185 0.889 TRUE 0.697 1.013 alpha_0 -0.134 0.349 -0.960 -0.107 0.460 TRUE 0.630 1.108 alpha_ivel 0.173 0.230 -0.265 0.170 0.634 TRUE 0.771 1.007 sigma 1.558 0.285 1.107 1.522 2.269 FALSE 1.000 1.046 fit 81.587 15.266 60.488 78.693 121.967 FALSE 1.000 1.113 fit_new 77.232 17.521 51.540 74.137 120.784 FALSE 1.000 1.107 sumN 124.769 32.469 91.000 117.000 205.000 FALSE 1.000 1.136 deviance 2154.674 16.230 2128.274 2152.758 2191.424 FALSE 1.000 1.077 n.eff beta_0 370 beta_ele 88 beta_for 277 beta_ele2 180 alpha_0 33 alpha_ivel 329 sigma 56 fit 32 fit_new 32 sumN 33 deviance 36 **WARNING** Rhat values indicate convergence failure. Rhat is the potential scale reduction factor (at convergence, Rhat=1). For each parameter, n.eff is a crude measure of effective sample size. overlap0 checks if 0 falls in the parameter's 95% credible interval. f is the proportion of the posterior with the same sign as the mean; i.e., our confidence that the parameter is positive or negative. DIC info: (pD = var(deviance)/2) pD = 124.3 and DIC = 2278.968 DIC is an estimate of expected predictive error (lower is better).
pp.check(jags_pln, "fit","fit_new")
stats <- t(sapply(list(jags_covs2, jags_nb, jags_zip, jags_pln),
function(x) c(mean=x$mean$beta_ele, lower=x$q2.5$beta_ele, upper=x$q97.5$beta_ele)))
plot(1:4, stats[,1], pch=19, xaxt='n', xlim=c(0.5, 4.5),
ylim=c(-2.5, -0.5), xlab="", ylab="beta_ele")
axis(1, at=1:4, labels=c("Pois","NB","ZIP","PLN"))
segments(1:4, stats[,2], 1:4, stats[,3])
stats <- t(sapply(list(jags_covs2, jags_nb, jags_zip, jags_pln),
function(x) c(mean=x$mean$sumN, lower=x$q2.5$sumN, upper=x$q97.5$sumN)))
plot(1:4, stats[,1], pch=19, xaxt='n', xlim=c(0.5, 4.5),
ylim=c(50, 210), xlab="", ylab="sumN")
axis(1, at=1:4, labels=c("Pois","NB","ZIP","PLN"))
segments(1:4, stats[,2], 1:4, stats[,3])
unmarked
¶Look at the data again:
library(unmarked)
data(mallard)
head(mallard.y)
head(mallard.site)
y.1 | y.2 | y.3 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 0 |
3 | 2 | 1 |
0 | 0 | 0 |
3 | 0 | 3 |
0 | 0 | 0 |
elev | length | forest | |
---|---|---|---|
<dbl> | <dbl> | <dbl> | |
1 | -1.173 | 0.801 | -1.156 |
2 | -1.127 | 0.115 | -0.501 |
3 | -0.198 | -0.479 | -0.101 |
4 | -0.105 | 0.315 | 0.008 |
5 | -1.034 | -1.102 | -1.193 |
6 | -0.848 | 0.741 | 0.917 |
umf <- unmarkedFramePCount(y = mallard.y, siteCovs = mallard.site)
head(umf)
Data frame representation of unmarkedFrame object. y.1 y.2 y.3 elev length forest 1 0 0 0 -1.173 0.801 -1.156 2 0 0 0 -1.127 0.115 -0.501 3 3 2 1 -0.198 -0.479 -0.101 4 0 0 0 -0.105 0.315 0.008 5 3 0 3 -1.034 -1.102 -1.193 6 0 0 0 -0.848 0.741 0.917 7 0 0 0 -0.910 0.115 -1.083 8 0 0 0 -1.003 -1.007 -0.792 9 0 0 0 -0.058 -0.913 0.553 10 0 0 0 -0.631 1.556 0.808
unmarked
function pcount
pcount
fits the N-mixture model: does not need to be point-count data!K
, an upper bound on possible site abundancenmix_null <- pcount(~1~1, umf, K = 20)
summary(nmix_null)
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ 1, data = umf, K = 20) Abundance (log-scale): Estimate SE z P(>|z|) -1.06 0.118 -9 2.17e-19 Detection (logit-scale): Estimate SE z P(>|z|) 0.611 0.17 3.59 0.00033 AIC: 631.8909 Number of sites: 235 ID of sites removed due to NA: 12 69 118 146 optim convergence code: 0 optim iterations: 15 Bootstrap iterations: 0
Estimates are on the transformed scale! To get them on the original scale, use predict
.
predict(nmix_null, type='state')[1,]
Warning message: “4 sites have been discarded because of missing data.”
Predicted | SE | lower | upper | |
---|---|---|---|---|
<dbl> | <dbl> | <dbl> | <dbl> | |
1 | 0.3460371 | 0.04078127 | 0.2746671 | 0.4359521 |
predict(nmix_null, type='det')[1,]
Warning message: “4 sites have been discarded because of missing data.”
Predicted | SE | lower | upper | |
---|---|---|---|---|
<dbl> | <dbl> | <dbl> | <dbl> | |
1 | 0.6482038 | 0.03881639 | 0.5689397 | 0.7200641 |
max(umf@y, na.rm=TRUE)
test_K <- function(K){
fit <- suppressWarnings(pcount(~1~1, umf, K=K))
exp(coef(fit)[1])
}
kvals <- c(13,14,15,20,25,30)
lams <- sapply(kvals, test_K)
plot(kvals, lams, type='o', pch=19, xlim=c(10, 30),
xlab="K", ylab="lambda estimate")
abline(v=12, col='red', lty=2)
Just need to change the formulas
nmix_covs <- pcount(~1~elev+forest, umf, K = 20)
nmix_covs
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest, data = umf, K = 20) Abundance: Estimate SE z P(>|z|) (Intercept) -1.905 0.228 -8.34 7.58e-17 elev -1.317 0.222 -5.93 2.95e-09 forest -0.738 0.163 -4.53 5.79e-06 Detection: Estimate SE z P(>|z|) 0.492 0.188 2.62 0.00878 AIC: 530.7381
The estimates are a little different from JAGS, but estimates in both cases are quite uncertain
data.frame(JAGS=unlist(jags_covs$mean[1:4]),
unmarked=coef(nmix_covs))
unm <- c(coef(nmix_covs)[1:3], plogis(coef(nmix_covs)[4]))
data.frame(JAGS=unlist(jags_covs$mean[1:4]),
unmarked=unm)
JAGS | unmarked | |
---|---|---|
<dbl> | <dbl> | |
beta_0 | -2.3535487 | -1.9051037 |
beta_ele | -1.6609773 | -1.3167989 |
beta_for | -0.9428308 | -0.7378125 |
p | 0.6108338 | 0.4921321 |
JAGS | unmarked | |
---|---|---|
<dbl> | <dbl> | |
beta_0 | -2.3535487 | -1.9051037 |
beta_ele | -1.6609773 | -1.3167989 |
beta_for | -0.9428308 | -0.7378125 |
p | 0.6108338 | 0.6206086 |
newdata
, holding other covariates at mean or medianpredict
to generate corresponding abundance values# sequence of covariate values
elev_rng <- range(mallard.site$elev)
elev_seq <- seq(elev_rng[1], elev_rng[2], length.out=100)
# insert into newdata
nd <- data.frame(elev=elev_seq, forest=median(mallard.site$forest))
# predict
pr <- predict(nmix_covs, type='state', newdata=nd)
head(pr)
Predicted | SE | lower | upper | |
---|---|---|---|---|
<dbl> | <dbl> | <dbl> | <dbl> | |
1 | 1.0343542 | 0.2120818 | 0.6920552 | 1.545959 |
2 | 0.9824581 | 0.1955079 | 0.6651598 | 1.451116 |
3 | 0.9331658 | 0.1802507 | 0.6390581 | 1.362628 |
4 | 0.8863465 | 0.1662269 | 0.6137164 | 1.280087 |
5 | 0.8418763 | 0.1533586 | 0.5891027 | 1.203111 |
6 | 0.7996373 | 0.1415724 | 0.5651860 | 1.131344 |
plot(elev_seq, pr$Predicted, type='l')
# add CIs
plot(elev_seq, pr$Predicted, type='l', ylim=c(0, 1.5))
polygon(c(elev_seq, rev(elev_seq)), c(pr$lower, rev(pr$upper)), col='lightgrey', border=NA)
lines(elev_seq, pr$Predicted)
plotEffects(nmix_covs, type = "state", covariate = "elev")
Actually, we will use tools in AICcmodavg
package
Process:
Calculate manually in R:
yhat <- fitted(nmix_covs)
sum((umf@y - yhat)^2 / yhat, na.rm=TRUE)
library(AICcmodavg)
Nmix.gof.test(nmix_covs, nsim = 30)
Chi-square goodness-of-fit for N-mixture model of 'unmarkedFitPCount' class Observed chi-square statistic = 1405.956 Number of bootstrap samples = 30 P-value = 0 Quantiles of bootstrapped statistics: 0% 25% 50% 75% 100% 459 558 625 709 987 Estimate of c-hat = 2.17
nmix_covs_nb <- pcount(~1~elev+forest, umf, K = 20, mixture = "NB")
summary(nmix_covs_nb)
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest, data = umf, K = 20, mixture = "NB") Abundance (log-scale): Estimate SE z P(>|z|) (Intercept) -1.753 0.269 -6.53 6.67e-11 elev -1.378 0.266 -5.19 2.14e-07 forest -0.725 0.215 -3.37 7.40e-04 Detection (logit-scale): Estimate SE z P(>|z|) 0.00988 0.243 0.0407 0.968 Dispersion (log-scale): Estimate SE z P(>|z|) -0.885 0.317 -2.79 0.00525 AIC: 481.0938 Number of sites: 235 ID of sites removed due to NA: 12 69 118 146 optim convergence code: 0 optim iterations: 41 Bootstrap iterations: 0
Here the dispersion estimate is $\mathrm{log}(r)$, not $\phi$
Nmix.gof.test(nmix_covs_nb, nsim = 30)
Chi-square goodness-of-fit for N-mixture model of 'unmarkedFitPCount' class Observed chi-square statistic = 1475.87 Number of bootstrap samples = 30 P-value = 0.1 Quantiles of bootstrapped statistics: 0% 25% 50% 75% 100% 791 898 982 1117 2413 Estimate of c-hat = 1.34
nmix_covs_zip <- pcount(~1~elev+forest, umf, K = 20, mixture = "ZIP")
summary(nmix_covs_zip)
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest, data = umf, K = 20, mixture = "ZIP") Abundance (log-scale): Estimate SE z P(>|z|) (Intercept) -1.097 0.304 -3.62 3.0e-04 elev -1.274 0.238 -5.35 8.9e-08 forest -0.614 0.181 -3.38 7.2e-04 Detection (logit-scale): Estimate SE z P(>|z|) 0.261 0.235 1.11 0.266 Zero-inflation (logit-scale): Estimate SE z P(>|z|) -0.000622 0.345 -0.0018 0.999 AIC: 511.0829 Number of sites: 235 ID of sites removed due to NA: 12 69 118 146 optim convergence code: 0 optim iterations: 49 Bootstrap iterations: 0
Nmix.gof.test(nmix_covs_zip, nsim = 30)
Chi-square goodness-of-fit for N-mixture model of 'unmarkedFitPCount' class Observed chi-square statistic = 1388.716 Number of bootstrap samples = 30 P-value = 0 Quantiles of bootstrapped statistics: 0% 25% 50% 75% 100% 591 717 757 831 973 Estimate of c-hat = 1.8
umf@siteCovs$id <- factor(1:numSites(umf))
nmix_covs_pln <- pcount(~1~elev+forest+(1|id), umf, K = 20)
nmix_covs_pln
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest + (1 | id), data = umf, K = 20) Abundance: Random effects: Groups Name Variance Std.Dev. id (Intercept) 2.397 1.548 Fixed effects: Estimate SE z P(>|z|) (Intercept) -2.814 0.398 -7.08 1.47e-12 elev -1.376 0.294 -4.69 2.76e-06 forest -0.742 0.244 -3.04 2.40e-03 Detection: Estimate SE z P(>|z|) 0.0218 0.226 0.0966 0.923 AIC: 472.0072
fl <- fitList(null=nmix_null, covs=nmix_covs, nb=nmix_covs_nb, zip=nmix_covs_zip)
modSel(fl)
Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.”
nPars AIC delta AICwt cumltvWt nb 5 481.09 0.00 1.0e+00 1.00 zip 5 511.08 29.99 3.1e-07 1.00 covs 4 530.74 49.64 1.7e-11 1.00 null 2 631.89 150.80 1.8e-33 1.00
unmarked
we have to "integrate out" the latent abundancer <- ranef(nmix_covs_nb)
r
Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.”
Mean Mode 2.5% 97.5% [1,] 0.046984840 0 0 1 [2,] 0.041395270 0 0 1 [3,] 3.420860989 3 3 5 [4,] 0.017222689 0 0 0 [5,] 4.169619341 4 3 7 [6,] 0.021924662 0 0 0 [7,] 0.042814162 0 0 1 [8,] 0.041867701 0 0 1 [9,] 0.012209217 0 0 0 [10,] 0.019017597 0 0 0 [11,] 0.004868602 0 0 0 [12,] 0.042369172 0 0 1 [13,] 0.012868910 0 0 0 [14,] 0.030768078 0 0 1 [15,] 0.013552704 0 0 0 [16,] 0.006787598 0 0 0 [17,] 1.236817812 1 1 3 [18,] 0.035243109 0 0 1 [19,] 1.570388818 1 1 3 [20,] 0.004115638 0 0 0 [21,] 0.033620157 0 0 1 [22,] 0.020767930 0 0 0 [23,] 0.005920753 0 0 0 [24,] 0.033426545 0 0 1 [25,] 17.400203488 18 14 20 [26,] 0.036955636 0 0 1 [27,] 0.018010432 0 0 0 [28,] 0.007449491 0 0 0 [29,] 0.013189178 0 0 0 [30,] 1.090162820 1 1 2 [31,] 1.289206263 1 1 3 [32,] 0.045600556 0 0 1 [33,] 0.009331223 0 0 0 [34,] 0.021110646 0 0 0 [35,] 0.029696489 0 0 1 [36,] 0.015875879 0 0 0 [37,] 0.001977142 0 0 0 [38,] 0.006563806 0 0 0 [39,] 0.016031427 0 0 0 [40,] 1.128675124 1 1 2 [41,] 0.003354656 0 0 0 [42,] 0.004217539 0 0 0 [43,] 0.032385161 0 0 1 [44,] 0.025701403 0 0 0 [45,] 0.007267892 0 0 0 [46,] 0.029316871 0 0 1 [47,] 0.024588414 0 0 0 [48,] 1.161669381 1 1 2 [49,] 0.007361064 0 0 0 [50,] 0.015598795 0 0 0 [51,] 1.023594071 1 1 1 [52,] 0.016392929 0 0 0 [53,] 0.011800553 0 0 0 [54,] 0.039073809 0 0 1 [55,] 0.016360014 0 0 0 [56,] 0.012864006 0 0 0 [57,] 0.003536612 0 0 0 [58,] 0.039583086 0 0 1 [59,] 0.017127829 0 0 0 [60,] 2.387034184 2 2 4 [61,] 0.016996642 0 0 0 [62,] 0.045253570 0 0 1 [63,] 0.003969714 0 0 0 [64,] 1.146730304 1 1 2 [65,] 0.032294674 0 0 1 [66,] 0.035034680 0 0 1 [67,] 0.025138904 0 0 0 [68,] 7.423940054 7 5 11 [69,] 0.016289323 0 0 0 [70,] 0.007188429 0 0 0 [71,] 0.006177321 0 0 0 [72,] 0.036527938 0 0 1 [73,] 0.021187202 0 0 0 [74,] 0.025523797 0 0 0 [75,] 0.001530405 0 0 0 [76,] 0.001827743 0 0 0 [77,] 0.002538851 0 0 0 [78,] 0.006844917 0 0 0 [79,] 0.009829618 0 0 0 [80,] 0.020434962 0 0 0 [81,] 0.029248528 0 0 1 [82,] 0.036507427 0 0 1 [83,] 1.506835519 1 1 3 [84,] 0.016223472 0 0 0 [85,] 0.005659877 0 0 0 [86,] 0.003538239 0 0 0 [87,] 0.029832112 0 0 1 [88,] 0.217707648 0 0 2 [89,] 1.056936591 1 1 2 [90,] 0.019822430 0 0 0 [91,] 0.035276331 0 0 1 [92,] 0.005900424 0 0 0 [93,] 0.007346588 0 0 0 [94,] 0.033663017 0 0 1 [95,] 0.006091983 0 0 0 [96,] 0.041178389 0 0 1 [97,] 0.007692091 0 0 0 [98,] 0.012568247 0 0 0 [99,] 0.035022527 0 0 1 [100,] 1.158387684 1 1 2 [101,] 0.009788777 0 0 0 [102,] 0.002055558 0 0 0 [103,] 0.002153691 0 0 0 [104,] 0.005607716 0 0 0 [105,] 0.021262460 0 0 0 [106,] 1.236582664 1 1 3 [107,] 0.023211501 0 0 0 [108,] 0.005323028 0 0 0 [109,] 0.010051920 0 0 0 [110,] 0.040827652 0 0 1 [111,] 1.445577679 1 1 3 [112,] 0.001838545 0 0 0 [113,] 0.013663635 0 0 0 [114,] 0.022028534 0 0 0 [115,] 1.136665438 1 1 2 [116,] 0.044880345 0 0 1 [117,] 0.048964632 0 0 1 [118,] 0.015838401 0 0 0 [119,] 0.022368638 0 0 0 [120,] 1.304049417 1 1 3 [121,] 5.399131779 5 4 8 [122,] 0.021463651 0 0 0 [123,] 0.003422626 0 0 0 [124,] 0.023733418 0 0 0 [125,] 0.033330007 0 0 1 [126,] 0.044823512 0 0 1 [127,] 0.046542188 0 0 1 [128,] 1.289383433 1 1 3 [129,] 0.003637699 0 0 0 [130,] 3.598665972 3 3 6 [131,] 0.040943411 0 0 1 [132,] 0.046600089 0 0 1 [133,] 0.031201219 0 0 1 [134,] 2.479394103 2 2 4 [135,] 1.254382435 1 1 3 [136,] 0.006211823 0 0 0 [137,] 0.008327797 0 0 0 [138,] 0.009882644 0 0 0 [139,] 1.189427991 1 1 2 [140,] 0.042224498 0 0 1 [141,] 0.038790389 0 0 1 [142,] 0.028642725 0 0 1 [143,] 0.009590561 0 0 0 [144,] 0.011462420 0 0 0 [145,] 2.400826404 2 2 4 [146,] 0.035874812 0 0 1 [147,] 0.003721906 0 0 0 [148,] 0.001907943 0 0 0 [149,] 0.006156528 0 0 0 [150,] 5.955966574 6 4 9 [151,] 0.021926870 0 0 0 [152,] 0.010832767 0 0 0 [153,] 0.012729012 0 0 0 [154,] 2.263263834 2 2 4 [155,] 0.021731719 0 0 0 [156,] 0.021731719 0 0 0 [157,] 0.037377593 0 0 1 [158,] 0.019970002 0 0 0 [159,] 0.004523068 0 0 0 [160,] 0.037889244 0 0 1 [161,] 0.004224435 0 0 0 [162,] 0.010942642 0 0 0 [163,] 0.012693808 0 0 0 [164,] 0.007431375 0 0 0 [165,] 0.011382292 0 0 0 [166,] 0.010954780 0 0 0 [167,] 0.007485956 0 0 0 [168,] 0.022584640 0 0 0 [169,] 0.012335548 0 0 0 [170,] 0.007220592 0 0 0 [171,] 0.003451671 0 0 0 [172,] 0.018118934 0 0 0 [173,] 4.610648264 4 3 7 [174,] 1.540941761 1 1 3 [175,] 0.010412973 0 0 0 [176,] 0.028859646 0 0 1 [177,] 0.002868679 0 0 0 [178,] 2.882512706 2 2 5 [179,] 0.015201274 0 0 0 [180,] 0.006996819 0 0 0 [181,] 0.005142620 0 0 0 [182,] 0.005795895 0 0 0 [183,] 0.009830855 0 0 0 [184,] 0.005275956 0 0 0 [185,] 0.005025610 0 0 0 [186,] 1.125139987 1 1 2 [187,] 0.018404511 0 0 0 [188,] 1.565865151 1 1 3 [189,] 0.003169450 0 0 0 [190,] 0.002021378 0 0 0 [191,] 0.014749085 0 0 0 [192,] 1.578976603 1 1 3 [193,] 0.019504834 0 0 0 [194,] 0.010452845 0 0 0 [195,] 0.016969642 0 0 0 [196,] 1.079748248 1 1 2 [197,] 0.041302157 0 0 1 [198,] 3.010439203 3 2 5 [199,] 2.071956916 2 2 3 [200,] 1.035223644 1 1 2 [201,] 0.014757212 0 0 0 [202,] 0.008609226 0 0 0 [203,] 0.014538496 0 0 0 [204,] 0.009595070 0 0 0 [205,] 0.012969280 0 0 0 [206,] 0.007582165 0 0 0 [207,] 0.008532701 0 0 0 [208,] 0.002666074 0 0 0 [209,] 1.008689515 1 1 1 [210,] 0.001487545 0 0 0 [211,] 0.001403987 0 0 0 [212,] 0.001457889 0 0 0 [213,] 0.007188429 0 0 0 [214,] 0.002117769 0 0 0 [215,] 0.002981001 0 0 0 [216,] 0.010093609 0 0 0 [217,] 0.010093609 0 0 0 [218,] 0.006760214 0 0 0 [219,] 0.008271254 0 0 0 [220,] 0.004494322 0 0 0 [221,] 0.003653496 0 0 0 [222,] 0.006760214 0 0 0 [223,] 0.017933077 0 0 0 [224,] 0.012278793 0 0 0 [225,] 0.021055879 0 0 0 [226,] 0.014881020 0 0 0 [227,] 0.021524680 0 0 0 [228,] 0.010393372 0 0 0 [229,] 0.012278793 0 0 0 [230,] 0.014881020 0 0 0 [231,] 0.017135632 0 0 0 [232,] 0.017933077 0 0 0 [233,] 0.010093609 0 0 0 [234,] 0.010093609 0 0 0 [235,] 0.008271254 0 0 0
head(bup(r))
head(bup(r, stat='mode'))
Use unmarked to fit the following model.
mallard.obs
, you will need to modify the unmarkedFrame
)Check goodness-of-fit.
Compare with the other models using model selection.
I(elev^2)
umf <- unmarkedFramePCount(y = mallard.y, siteCovs = mallard.site, obsCovs = mallard.obs)
nmix_obs <- pcount(~ivel~elev+forest+I(elev^2), umf, K = 20)
nmix_obs
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~ivel ~ elev + forest + I(elev^2), data = umf, K = 20) Abundance: Estimate SE z P(>|z|) (Intercept) -1.88792 0.283 -6.6696 2.57e-11 elev -1.35446 0.231 -5.8597 4.64e-09 forest -0.73976 0.170 -4.3539 1.34e-05 I(elev^2) 0.00943 0.245 0.0385 9.69e-01 Detection: Estimate SE z P(>|z|) (Intercept) 0.420 0.214 1.97 0.0493 ivel 0.423 0.171 2.47 0.0136 AIC: 528.2189
suppressWarnings(Nmix.gof.test(nmix_obs, nsim=30))
Chi-square goodness-of-fit for N-mixture model of 'unmarkedFitPCount' class Observed chi-square statistic = 1479.577 Number of bootstrap samples = 30 P-value = 0 Quantiles of bootstrapped statistics: 0% 25% 50% 75% 100% 498 587 630 718 1010 Estimate of c-hat = 2.23
# re-fit to make sure all models use the same dataset
nmix_null <- pcount(~1~1, umf, K=20)
nmix_covs <- pcount(~1~forest+elev, umf, K=20)
fl <- fitList(nmix_null=nmix_null, nmix_covs=nmix_covs, nmix_obs=nmix_obs)
modSel(fl)
Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.” Warning message: “4 sites have been discarded because of missing data.”
nPars AIC delta AICwt cumltvWt nmix_obs 6 528.22 0.00 7.8e-01 0.78 nmix_covs 4 530.74 2.52 2.2e-01 1.00 nmix_null 2 631.89 103.67 2.4e-23 1.00
A common situation:
Potential solution: "stacking"!
Potential issue:
Could ignore this if you don't expect much correlation in abundance at a site among years, or add a site-level random effect.
We don't have a convenient dataset with multiple years of data, so I'll just simulate some based on our mallard
dataset and our model fit.
new_data <- unmarked::simulate(nmix_covs, 2, na.rm=FALSE)
lapply(new_data, head)
1 | 1 | 1 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
2 | 2 | 1 |
2 | 2 | 1 |
0 | 0 | 1 |
0 | 0 | 0 |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
Original (real) data is year 1, and simulated datasets are years 2 and 3
y_all <- rbind(umf@y, new_data[[1]], new_data[[2]])
# "Site" (site-year) covariates
sc_all <- rbind(umf@siteCovs, umf@siteCovs, umf@siteCovs)
sc_all$site <- factor(rep(1:numSites(umf), 3))
sc_all$year <- rep(1:3, each=numSites(umf))
head(sc_all)
elev | length | forest | site | year | |
---|---|---|---|---|---|
<dbl> | <dbl> | <dbl> | <fct> | <int> | |
1 | -1.173 | 0.801 | -1.156 | 1 | 1 |
2 | -1.127 | 0.115 | -0.501 | 2 | 1 |
3 | -0.198 | -0.479 | -0.101 | 3 | 1 |
4 | -0.105 | 0.315 | 0.008 | 4 | 1 |
5 | -1.034 | -1.102 | -1.193 | 5 | 1 |
6 | -0.848 | 0.741 | 0.917 | 6 | 1 |
# Obs covariates
oc_all <- rbind(umf@obsCovs, umf@obsCovs, umf@obsCovs)
Make the combined unmarkedFrame
umf_all <- unmarkedFramePCount(y=y_all, siteCovs=sc_all, obsCovs=oc_all)
summary(umf_all)
unmarkedFrame Object 717 sites Maximum number of observations per site: 3 Mean number of observations per site: 2.92 Sites with at least one detection: 145 Tabulation of y observations: 0 1 2 3 4 5 7 10 12 <NA> 1778 230 56 15 9 2 1 1 1 58 Site-level covariates: elev length forest site Min. :-1.436000 Min. :-4.945000 Min. :-1.2650000 1 : 3 1st Qu.:-0.972000 1st Qu.:-0.563000 1st Qu.:-0.9740000 2 : 3 Median :-0.198000 Median : 0.045000 Median :-0.0650000 3 : 3 Mean :-0.000046 Mean :-0.000029 Mean : 0.0000669 4 : 3 3rd Qu.: 0.994000 3rd Qu.: 0.626000 3rd Qu.: 0.8080000 5 : 3 Max. : 2.434000 Max. : 2.255000 Max. : 2.2990000 6 : 3 (Other):699 year Min. :1 1st Qu.:1 Median :2 Mean :2 3rd Qu.:3 Max. :3 Observation-level covariates: ivel date Min. :-1.75300 Min. :-2.90400 1st Qu.:-0.66600 1st Qu.:-1.11900 Median :-0.13900 Median :-0.11900 Mean : 0.00002 Mean : 0.00007 3rd Qu.: 0.54900 3rd Qu.: 1.31000 Max. : 5.98000 Max. : 3.81000 NA's :156 NA's :126
Not accounting for pseudoreplicated sites:
mod_stack <- pcount(~1~elev+forest+year, umf_all, K=20)
mod_stack
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest + year, data = umf_all, K = 20) Abundance: Estimate SE z P(>|z|) (Intercept) -1.7821 0.2054 -8.677 4.06e-18 elev -1.2438 0.1211 -10.275 9.17e-25 forest -0.6809 0.0914 -7.451 9.27e-14 year -0.0344 0.0819 -0.421 6.74e-01 Detection: Estimate SE z P(>|z|) 0.488 0.107 4.57 4.83e-06 AIC: 1534.382
Accounting for pseudoreplicated sites with a random effect:
mod_stack2 <- pcount(~1~elev+forest+year+(1|site), umf_all, K=20)
mod_stack2
Warning message: “4 sites have been discarded because of missing data.”
Call: pcount(formula = ~1 ~ elev + forest + year + (1 | site), data = umf_all, K = 20) Abundance: Random effects: Groups Name Variance Std.Dev. site (Intercept) 0.271 0.52 Fixed effects: Estimate SE z P(>|z|) (Intercept) -1.8956 0.2148 -8.823 1.11e-18 elev -1.2477 0.1318 -9.470 2.80e-21 forest -0.6738 0.1056 -6.383 1.73e-10 year -0.0395 0.0819 -0.483 6.29e-01 Detection: Estimate SE z P(>|z|) 0.449 0.111 4.06 4.98e-05 AIC: 1521.633
ubms
¶library(ubms)
nmix_stan <- stan_pcount(~1~elev+forest, umf, K = 20, chains = 3, iter = 300, refresh = 0)
nmix_stan
Attaching package: ‘ubms’ The following objects are masked from ‘package:unmarked’: fitList, projected The following object is masked from ‘package:base’: gamma Warning message: “Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable. Running the chains for more iterations may help. See https://mc-stan.org/misc/warnings.html#bulk-ess” Warning message: “Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable. Running the chains for more iterations may help. See https://mc-stan.org/misc/warnings.html#tail-ess” Warning message: “Some Pareto k diagnostic values are too high. See help('pareto-k-diagnostic') for details. ”
Call: stan_pcount(formula = ~1 ~ elev + forest, data = umf, K = 20, chains = 3, iter = 300, refresh = 0) Abundance (log-scale): Estimate SD 2.5% 97.5% n_eff Rhat (Intercept) -1.954 0.271 -2.53 -1.490 194 1.01 elev -1.353 0.266 -1.89 -0.921 218 1.00 forest -0.756 0.176 -1.13 -0.431 383 1.00 Detection (logit-scale): Estimate SD 2.5% 97.5% n_eff Rhat 0.48 0.191 0.123 0.828 326 1 LOOIC: 537.534 Runtime: 12.186 sec
Nest <- posterior_predict(nmix_stan, "z")
dim(Nest)
hist(apply(Nest, 1, sum, na.rm=TRUE), main="sumN", xlab="sumN")
Demonstration of how prior settings can affect coefficient estimates
Set the prior_intercept_state
argument in stan_pcount
vary_prior <- function(prior){
suppressWarnings(stan_pcount(~1~elev+forest, umf, K = 20, chains = 3, iter = 300, refresh = 0,
prior_intercept_state = prior))
}
priors <- list(p5=normal(0, 5), p1=normal(0, 1), p25=normal(0, 2.5), p05=normal(0, 0.5), p25=normal(0, 0.1))
mods <- lapply(priors, vary_prior)
stats <- t(sapply(mods, function(x) as.numeric(summary(x, 'state')[1,c(1,4,8)])))
plot(1:5, stats[,1], ylim=c(-2.5, 0), pch=19, xaxt='n',
xlab="", ylab="Intercept estimate")
axis(1, at=1:5, labels=c("N(0,5)","N(0,2.5)","N(0,1)", "N(0,0.5)","N(0,0.1)"))
segments(1:5, stats[,2], 1:5, stats[,3])
NIMBLE
is a general-purpose model fitting enginelibrary(nimble)
nimble version 0.13.2 is loaded. For more information on NIMBLE and a User Manual, please visit https://R-nimble.org. Note for advanced users who have written their own MCMC samplers: As of version 0.13.0, NIMBLE's protocol for handling posterior predictive nodes has changed in a way that could affect user-defined samplers in some situations. Please see Section 15.5.1 of the User Manual. Attaching package: ‘nimble’ The following object is masked from ‘package:unmarked’: simulate The following object is masked from ‘package:stats’: simulate
nmix_code <- nimbleCode({
# State model
for (i in 1:M){
N[i] ~ dpois(lambda[i])
log(lambda[i]) <- beta_0 + beta_ele * elev[i] + beta_for * forest[i]
}
beta_0 ~ dunif(-10, 10)
beta_ele ~ dnorm(0, 0.01)
beta_for ~ dnorm(0, 0.01)
# Detection model
for (i in 1:M){
for (j in 1:J){
y[i,j] ~ dbinom(p, N[i])
}
}
p ~ dunif(0,1)
sumN <- sum(N[])
})
pars <- c("beta_0", "beta_ele", "beta_for", "p")
inits <- function() list(N = Ninit)
nimble_covs <- nimbleMCMC(code = nmix_code,
constants = jags_data,
inits = inits,
monitors = pars,
nchains = 3,
niter=3000,
nburnin=2000,
summary = TRUE,
samplesAsCodaMCMC = TRUE)
Defining model [Note] 'ivel' is provided in 'constants' but not used in the model code and is being ignored. [Note] Using 'y' (given within 'constants') as data. Building model Setting data and initial values Running calculate on model [Note] Any error reports that follow may simply reflect missing values in model variables. Checking model sizes and dimensions [Note] This model is not fully initialized. This is not an error. To see which variables are not initialized, use model$initializeInfo(). For more information on model initialization, see help(modelInitialization). Checking model calculations [Note] NAs were detected in model variables: beta_0, logProb_beta_0, beta_ele, logProb_beta_ele, beta_for, logProb_beta_for, p, logProb_p, lambda, logProb_N, N, logProb_y, y, sumN. Compiling [Note] This may take a minute. [Note] Use 'showCompilerOutput = TRUE' to see C++ compilation details. running chain 1...
warning: problem initializing stochastic node N[40]: logProb less than -1e12. warning: problem initializing stochastic node N[64]: logProb less than -1e12. warning: problem initializing stochastic node N[72]: logProb less than -1e12. warning: problem initializing stochastic node N[86]: logProb less than -1e12. warning: problem initializing stochastic node N[204]: logProb less than -1e12. warning: problem initializing stochastic node N[206]: logProb less than -1e12. warning: problem initializing stochastic node N[207]: logProb less than -1e12. warning: problem initializing stochastic node N[210]: logProb less than -1e12. warning: problem initializing stochastic node N[211]: logProb less than -1e12. warning: problem initializing stochastic node N[217]: logProb less than -1e12. warning: problem initializing stochastic node N[220]: logProb less than -1e12. warning: problem initializing stochastic node N[221]: logProb less than -1e12. warning: problem initializing stochastic node N[222]: logProb less than -1e12. warning: problem initializing stochastic node N[223]: logProb less than -1e12. warning: problem initializing stochastic node N[224]: logProb less than -1e12. warning: problem initializing stochastic node N[225]: logProb less than -1e12. warning: problem initializing stochastic node N[226]: logProb less than -1e12. warning: problem initializing stochastic node N[228]: logProb less than -1e12. warning: problem initializing stochastic node N[230]: logProb less than -1e12. warning: problem initializing stochastic node N[233]: logProb less than -1e12. warning: problem initializing stochastic node N[234]: logProb less than -1e12. warning: problem initializing stochastic node N[237]: logProb less than -1e12. warning: problem initializing stochastic node N[238]: logProb less than -1e12. warning: problem initializing stochastic node N[239]: logProb less than -1e12. |-------------|-------------|-------------|-------------| |Warning: slice sampler reached maximum number of contractions for 'N[224]'. Current parameter value is 16. Warning: slice sampler reached maximum number of contractions for 'N[64]'. Current parameter value is 40. Warning: slice sampler reached maximum number of contractions for 'N[64]'. Current parameter value is 40. -------------------------------------------------------|
running chain 2...
warning: problem initializing stochastic node y[69, 1]: logProb is -Inf. warning: problem initializing stochastic node y[69, 2]: logProb is -Inf. warning: problem initializing stochastic node y[69, 3]: logProb is -Inf. warning: problem initializing stochastic node y[146, 3]: logProb is -Inf. |-------------|-------------|-------------|-------------| |-------------------------------------------------------|
running chain 3...
warning: problem initializing stochastic node y[222, 3]: logProb is -Inf. |-------------|-------------|-------------|-------------| |-------------------------------------------------------|
coda::traceplot(nimble_covs$samples)
nimble_covs$summary$all.chains
Mean | Median | St.Dev. | 95%CI_low | 95%CI_upp | |
---|---|---|---|---|---|
beta_0 | -1.9311467 | -1.9154466 | 0.23295557 | -2.4262519 | -1.5196816 |
beta_ele | -1.3398020 | -1.3210108 | 0.21367156 | -1.8186875 | -0.9539358 |
beta_for | -0.7354201 | -0.7312231 | 0.16262465 | -1.0655075 | -0.4295455 |
p | 0.6157582 | 0.6192895 | 0.04458034 | 0.5247495 | 0.7021781 |
NIMBLE
macros¶library(nimbleMacros)
nimbleOptions(enableMacroComments = FALSE)
priors <- nimbleMacros::priors
nimble_lp <- nimbleCode({
lambda[1:M] <- linPred(~elev+forest, link = log)
})
Attaching package: ‘nimbleMacros’ The following object is masked _by_ ‘.GlobalEnv’: priors
mod <- nimbleModel(nimble_lp, constants = jags_data)
mod$getCode()
Defining model [Note] 'y' is provided in 'constants' but not used in the model code and is being ignored. [Note] 'ivel' is provided in 'constants' but not used in the model code and is being ignored. [Note] 'J' is provided in 'constants' but not used in the model code and is being ignored. Building model Running calculate on model [Note] Any error reports that follow may simply reflect missing values in model variables. Checking model sizes and dimensions [Note] This model is not fully initialized. This is not an error. To see which variables are not initialized, use model$initializeInfo(). For more information on model initialization, see help(modelInitialization).
{ for (i_1 in 1:M) { log(lambda[i_1]) <- beta_Intercept + beta_elev * elev[i_1] + beta_forest * forest[i_1] } beta_Intercept ~ dunif(-100, 100) beta_elev ~ dnorm(0, sd = 100) beta_forest ~ dnorm(0, sd = 100) }
jags_data$group <- factor(sample(letters[1:5], jags_data$M, replace=TRUE))
nimble_lp2 <- nimbleCode({
lambda[1:M] <- linPred(~forest + (1|group), link = log)
})
mod <- nimbleModel(nimble_lp2, constants = jags_data)
mod$getCode()
Defining model [Note] 'y' is provided in 'constants' but not used in the model code and is being ignored. [Note] 'ivel' is provided in 'constants' but not used in the model code and is being ignored. [Note] 'elev' is provided in 'constants' but not used in the model code and is being ignored. [Note] 'J' is provided in 'constants' but not used in the model code and is being ignored. Building model Running calculate on model [Note] Any error reports that follow may simply reflect missing values in model variables. Checking model sizes and dimensions [Note] This model is not fully initialized. This is not an error. To see which variables are not initialized, use model$initializeInfo(). For more information on model initialization, see help(modelInitialization).
{ for (i_1 in 1:M) { log(lambda[i_1]) <- beta_Intercept + beta_forest * forest[i_1] + beta_group[group[i_1]] } beta_Intercept ~ dunif(-100, 100) beta_forest ~ dnorm(0, sd = 100) sd_group ~ T(dt(0, 0.01, 1), 0, ) for (i_2 in 1:5) { beta_group[i_2] ~ dnorm(0, sd = sd_group) } }
nimble_covs2 <- nimbleCode({
y[1:M, 1:J] ~ nmixture(~1~elev+forest+(1|group))
})
nimble_covs <- nimbleModel(nimble_covs2, constants = jags_data)
nimble_covs$getCode()
Defining model [Note] 'ivel' is provided in 'constants' but not used in the model code and is being ignored. [Note] Using 'y' (given within 'constants') as data. Building model Setting data and initial values Running calculate on model [Note] Any error reports that follow may simply reflect missing values in model variables. Checking model sizes and dimensions [Note] This model is not fully initialized. This is not an error. To see which variables are not initialized, use model$initializeInfo(). For more information on model initialization, see help(modelInitialization).
{ for (i_1 in 1:M) { log(lam[i_1]) <- state_Intercept + state_elev * elev[i_1] + state_forest * forest[i_1] + state_group[group[i_1]] } state_Intercept ~ dunif(-10, 10) state_elev ~ dnorm(0, 0.01) state_forest ~ dnorm(0, 0.01) state_sd_group ~ T(dt(0, 0.01, 1), 0, ) for (i_2 in 1:5) { state_group[i_2] ~ dnorm(0, sd = state_sd_group) } for (i_3 in 1:M) { for (i_4 in 1:J) { logit(p[i_3, i_4]) <- det_Intercept } } det_Intercept ~ dunif(-10, 10) for (i_5 in 1:M) { N[i_5] ~ dpois(lam[i_5]) } for (i_6 in 1:M) { for (i_7 in 1:J) { y[i_6, i_7] ~ dbinom(N[i_6], p[i_6, i_7]) } } }