Search code examples
bayesianjagsrjagshierarchical-bayesian

rjags error Invalid vector argument to ilogit


I'd like to compare a betareg regression vs. the same regression using rjags

library(betareg)
d = data.frame(p= sample(c(.1,.2,.3,.4),100, replace= TRUE),
               id = seq(1,100,1))

# I am looking to reproduce this regression with jags
b=betareg(p ~ id, data= d, 
          link = c("logit"), link.phi = NULL, type = c("ML"))
summary(b)

Below I am trying to do the same regression with rjags

#install.packages("rjags")
library(rjags)
jags_str = "
model {
#model

y ~ dbeta(alpha, beta)
alpha <- mu * phi
beta  <- (1-mu) * phi
logit(mu) <- a + b*id

#priors
a  ~ dnorm(0, .5)
b  ~ dnorm(0, .5)
t0 ~ dnorm(0, .5)
phi <- exp(t0)
}" 
id = d$id
y = d$p
model <- jags.model(textConnection(jags_str), 
                    data = list(y=y,id=id)
)
update(model, 10000, progress.bar="none"); # Burnin for 10000 samples
samp <- coda.samples(model, 
                     variable.names=c("mu"), 
                     n.iter=20000, progress.bar="none")

summary(samp)
plot(samp)

I get an error on this line

 model <- jags.model(textConnection(jags_str), 
                        data = list(y=y,id=id)
    )

Error in jags.model(textConnection(jags_str), data = list(y = y, id = id)) : 
  RUNTIME ERROR:
Invalid vector argument to ilogit

Can you advise

(1) how to fix the error

(2) how to set priors for the beta regression

Thank you.


Solution

  • This error occurs because you have supplied the id vector to the scalar function logit. In Jags inverse link functions cannot be vectorized. To address this, you need to use a for loop to go through each element of id. To do this I would probably add an additional element to your data list that denotes how long id is.

    d = data.frame(p= sample(c(.1,.2,.3,.4),100, replace= TRUE),
               id = seq(1,100,1), len_id = length(seq(1,100,1)))
    

    From there you just need to make a small edit to your jags code.

    for(i in 1:(len_id)){
    y[i] ~ dbeta(alpha[i], beta[i])
    alpha[i] <- mu[i] * phi
    beta[i]  <- (1-mu[i]) * phi
    logit(mu[i]) <- a + b*id[i]
    }
    

    However, if you track mu it is going to be a matrix that is 20000 (# of iterations) by 100 (length of id). You are likely more interested in the actual parameters (a, b, and phi).