rjagsrunjagsrjags

Fitting a multivariate dirlichet model in JAGS for R


I am trying to fit a a multivariate model to species composition data using JAGS, implemented in R. I have data on 3 species relative abundances (bounded between [0,1]), two of which are correlated. Here is code to generate similar data.

#generate some correlated fractional composition data.
y1 <- runif(100,10,200)
y2 <- y1*1.5 + rnorm(100, sd = 5)
y3 <- runif(100,10,200)
total <- y1+y2+y3
y1 <- y1/(total)
y2 <- y2/(total)
y3 <- y3/(total)
y <- data.frame(y1,y2,y3)

y is a data.frame of my three dependent variables, y1,y2 and y3. I would like to fit an intercept only model to these data, accounting for the covariance among the dependent variables using a dirlichet disitribution, the multivariate extension of the beta distribution.

I'm sort of stuck. I can code this up for a single dependent variable using a beta distribution fine using the runjags package in R as follows:

library(runjags)

#Write JAGS model, save as R object.
jags.model = "
model{
  # priors
  a0 ~ dnorm(0, .001)
  t0 ~ dnorm(0, .01)
  tau <- exp(t0)

  # likelihood for continuous component - predicted value on interval (0,1)
  for (i in 1:N){
    y[i] ~ dbeta(p[i], q[i])
    p[i] <- mu[i] * tau
    q[i] <- (1 - mu[i]) * tau
    logit(mu[i]) <- a0
  }
}
"

#generate JAGS data as list.
jags.data <- list(y = y1,
                  N = length(y1))

#Fit a JAGS model using run.jags
jags.out <- run.jags(jags.model,
                     data=jags.data,
                     adapt = 1000,
                     burnin = 1000,
                     sample = 2000,
                     n.chains=3,
                     monitor=c('a0'))

Mu question is: how can I extend this to the multivariate case, using the dirlichet distribution in JAGS, implemented in R? Bonus if we can account for covariance in the y matrix.


Solution

  • Here is a straightforward solution in JAGS, using the pseudo-data provided in the original question.

    JAGS data object:

    y <- as.matrix(y)
    jags.data <- list(y = y,
                      N = nrow(y),
                      N.spp = ncol(y))
    

    JAGS model as the R object jags.model:

    jags.model = "
    model {
        #setup priors for each species
        for(j in 1:N.spp){
          m0[j] ~ dgamma(1.0E-3, 1.0E-3) #intercept prior
        }
    
        #implement dirlichet
        for(i in 1:N){
        for(j in 1:N.spp){
             log(a0[i,j]) <- m0[j] ## eventually add linear model here
          }
         y[i,1:N.spp] ~ ddirch(a0[i,1:N.spp]) 
        }
    
    } #close model loop.
    "
    

    Go ahead and fit the model, monitoring the m0 intercept parameter, which is a vector, an intercept for each species group.

    #Fit a JAGS model using run.jags
    jags.out <- run.jags(jags.model,
                         data=jags.data,
                         adapt = 100,
                         burnin = 100,
                         sample = 200,
                         n.chains=3,
                         monitor=c('m0'))