I am trying to learn WINBUGS, and tried to build a small model, adjusted from an example in a text book, (code per below) that assumes a hidden population of infected carriers, with both a growth rate ("R0") and a removal rate (screening and treating) over time. However, i tend to get a range of error messages ("invalid or unexpected token scanned", "inits cannot be executed", etc.). Hence, can someone with more WINBUGS experience be so kind to eyeball whether i am making stupid mistakes in my understanding of WINBUGS? I am especially not sure whether the sequential update of the population (N.est[t+1] <- N.est[t] + newcases - obs) can be done in WINBUGS? Many thanks in advance
set.seed(1)
n.years <- 10 # Number of years
N1 <- 30 # Initial population size
rnode <- 0.3
attendance <- 0.4
#generating some data. the model has a hidden population of infected carriers that grows, and is screened periodically (with x% attendance). screened individuals are removed from the population. the observed cases are used in the bayesian framework (BUGS) to infer the hidden parameters
obs <- N <- newcases <- numeric(n.years)
N[1] <- N1
for (t in 1:(n.years-1)){
newcases[t] <- rbinom(n=1,size=N[t],prob=rnode) #
obs[t] <- rbinom(1, N[t], attendance) #observed cases
N[t+1] <- N[t] + newcases[t] - obs[t] }
# Specifying model in BUGS language
sink("ssm.bug")
cat("
model {
# Priors and constraints
N.est[1] ~ dbin(0.3, 100) # Prior for initial population size
rnode ~ dunif(0, 1) # Prior for R0
attendance ~ dunif(0, 1) # Prior for attendance at screening
# Likelihood
# State process
for (t in 1:(T-1)){
newcases ~ dbin(rnode,N.est[t])
obs ~ dbin(attendance,N.est[t])
N.est[t+1] <- N.est[t] + newcases - obs
}
",fill = TRUE)
sink()
# Bundle data
bugs.data <- list(obs = obs, T = n.years)
# Initial values
inits <- function(){list(rnode=0.5,attendance=0.5, N.est = c(runif(1, 20, 40), rep(NA, (n.years-1))))}
# Parameters monitored
parameters <- c("rnode", "attendance", "N.est")
# MCMC settings
ni <- 25000
nt <- 3
nb <- 10000
nc <- 3
# Call WinBUGS from R (BRT <1 min)
ssm <- bugs(bugs.data, inits, parameters, "ssm.bug", n.chains = nc, n.thin = nt, n.iter = ni, n.burnin = nb, debug = TRUE, bugs.directory = bugs.dir, working.directory = getwd())
# Define function to draw a graph to summarize results
graph.ssm <- function(ssm, N, y){
fitted <- lower <- upper <- numeric()
n.years <- length(y)
for (i in 1:n.years){
fitted[i] <- mean(ssm$sims.list$N.est[,i])
lower[i] <- quantile(ssm$sims.list$N.est[,i], 0.025)
upper[i] <- quantile(ssm$sims.list$N.est[,i], 0.975)}
m1 <- min(c(y, fitted, N, lower))
m2 <- max(c(y, fitted, N, upper))
par(mar = c(4.5, 4, 1, 1), cex = 1.2)
plot(0, 0, ylim = c(m1, m2), xlim = c(0.5, n.years), ylab = "Population size", xlab = "Year", las = 1, col = "black", type = "l", lwd = 2, frame = FALSE, axes = FALSE)
axis(2, las = 1)
axis(1, at = seq(0, n.years, 5), labels = seq(0, n.years, 5))
axis(1, at = 0:n.years, labels = rep("", n.years + 1), tcl = -0.25)
polygon(x = c(1:n.years, n.years:1), y = c(lower, upper[n.years:1]), col = "gray90", border = "gray90")
points(N, type = "l", col = "red", lwd = 2)
points(y, type = "l", col = "black", lwd = 2)
points(fitted, type = "l", col = "blue", lwd = 2)
legend(x = 1, y = m2, legend = c("True", "Observed", "Estimated"), lty = c(1, 1, 1), lwd = c(2, 2, 2), col = c("red", "black", "blue"), bty = "n", cex = 1)
}
# Execute function: Produce figure
graph.ssm(ssm, N, y)
In general, I would recommend delving into WinBUGS or OpenBUGS to debug your model first before you start automating things through R2WinBUGS (or R2OpenBUGS).
In your model above I found straight away that you were missing a closed parenthesis at the end, i.e. you need
model {
# Priors and constraints
N.est[1] ~ dbin(0.3, 100) # Prior for initial population size
rnode ~ dunif(0, 1) # Prior for R0
attendance ~ dunif(0, 1) # Prior for attendance at screening
# Likelihood
# State process
for (t in 1:(T-1)){
newcases ~ dbin(rnode,N.est[t])
obs ~ dbin(attendance,N.est[t])
N.est[t+1] <- N.est[t] + newcases - obs
}
}
OpenBUGS gives you a pretty good idea of these type of errors when you hit Model | Specification -> check model. The cursor jumps to the point where the error is occurring (at the end of your model code) if the model can not be compiled.