PyMC implementation of Smith et al. (2012) linked occupancy-abundance model
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
README.md
data.py
runmodel.py
snapper.py

README.md

snapper

PyMC implementation of Smith et al. (2012) linked occupancy-abundance model: http://www.esajournals.org/doi/abs/10.1890/12-0460.1

Created by M. Aaron MacNeil on 20/07/12.

"Smith, Adam Nicholas Howard, Marti Jane Anderson, and Russell Brian Millar. In press. Incorporating the intraspecific occupancy-abundance relationship into zero-inflated models. Ecology. http://dx.doi.org/10.1890/12-0460.1 Incorporating the intraspecific occupancy-abundance relationship into zero-inflated models

Adam Nicholas Howard Smith1,*, Marti Jane Anderson2, and Russell Brian Millar3 1Massey University, Albany Campus, New Zealand Institute for Advanced Study

2Massey University, New Zealand Institute for Advanced Study

3University of Auckland, Department of Statistics

Zero-inflated versions of standard distributions for count data are often required in order to account for excess zeros when modeling the abundance of organisms. Such distributions typically have as parameters λ, the mean of the count distribution, and π, the probability of an excess zero. Implementations of zero-inflated models in ecology typically model λ using a set of predictor variables, and π is fit either as a constant or with its own separate model. Neither of these approaches makes use of any relationship that might exist between π and λ. However, for many species, the rate of occupancy is closely and positively related to its average abundance. Here, this relationship was incorporated into the model by functionally linking π to λ, and demonstrated in a study of snapper (Pagrus auratus) in and around a marine reserve. This approach has several potential practical advantages, including better computational performance and more straightforward model interpretation. It is concluded that, where appropriate, directly linking π to λ can produce more ecologically accurate and parsimonious statistical models of species abundance data."

The Smith et al. code OpenBUGS code is below, from their supplemental information. This PyMC version is not identical to their approach (but close enough).

model{
  for(i in 1:N) {
    iz[i] <- step(sna[i] - 1)
    NBProbZero[i] <- pow(1 + lambda[i] / delta, -delta)
    nllZero[i] <- -log(p[i] + (1 - p[i])*NBProbZero[i])
    llNB[i] <- (loggam(delta + sna[i]) - loggam(delta) - loggam(sna[i] + 1) + sna[i] * log(lambda[i]) - sna[i] * log(delta) - (delta + sna[i]) * log(1 + lambda[i] / delta))
    nllNonZero[i] <- -(log(1 - p[i]) + llNB[i])	
    nll[i] <- iz[i] * nllNonZero[i] + (1 - iz[i]) * nllZero[i]	
    zero[i] <- 0
    zero[i] ~ dpois(nll[i]) 

    logit(p[i]) <- gamma0 + gamma1*eta[i]
    log(lambda[i]) <- eta[i]
    eta[i] <- llam.area[area[i]] + beta.season*season[i] + beta.year[year[i]]
  }

  # priors  
  delta ~ dgamma(0.0001,0.0001)
  gamma0 ~ dnorm(0.0, 0.01)
  gamma1 ~ dnorm(0.0, 0.01)

  for(j in 1:6) { llam.area[j] <- llam.reserve[reserve.in.area[j]] + beta.area[j]
                  beta.area[j] ~ dnorm(0.0, tau.area)  }

  llam.reserve[1] <- beta0 - beta.reserve
  llam.reserve[2] <- beta0 + beta.reserve

  beta0 ~ dnorm(0.0, 0.01)
  beta.reserve ~ dnorm(0.0, 0.01)
  beta.season ~ dnorm(0.0, 0.01)

  for(m in 1:9) { beta.year[m] ~ dnorm(0.0,tau.year) }

  # hyperpriors
  tau.year <- pow(sd.year, -2)
  sd.year ~ dunif(0,5)
  nlh.year <- log(1 + sd.year*sd.year)
  z.year <- 0
  z.year ~ dpois(nlh.year)

  tau.area <- pow(sd.area, -2)
  sd.area ~ dunif(0,5)
  nlh.area <- log(1 + sd.area*sd.area)
  z.area <- 0
  z.area ~ dpois(nlh.area)

  ## CALCULATIONS

  # variance components for fixed effects
  sd.reserve <- sd(llam.reserve[])
  sd.season <- sqrt( 2* pow(beta.season, 2) )

  # Means for no-reserve and reserve
  p.nores <- 1 / (1 + exp( -( gamma0 + gamma1*llam.reserve[1] )) )
  p.res <-  1 / (1 + exp( -( gamma0 + gamma1*llam.reserve[2] )) )
  mean.nores <- (1 - p.nores) * exp(llam.reserve[1])
  mean.res <- (1 - p.res) * exp(llam.reserve[2])
  res.effect <- mean.res / mean.nores
}