Background: I often find that when working with JAGS that I end up with a lot of JAGS scripts as I explore different models. After a while I might settle on a set of models that I'm going to report, but then there is the issue of keeping settings consistent across these models that are meant to be consistent. For example, the priors for parameters that are common should be consistent, or the variable names for parameters should be consistent. While consistency is not that difficult to achieve, it's often a little annoying. For example, I might decide that I want to call something theta rather than beta, and now all the scripts need updating. So I'm trying to work out how I can have one script that can serve multiple purposes.
Example:
Here's a simple example. Assume I have two models, one with time as a predictor and one without. I supply to jags a logical variable timevariable
to indicate whether I want to model time or not. Thus, I'd like to be able to write something like this.
for (i in 1:length(y)) {
if (timevariable) {
mu[i] <- beta1 + beta2 * time[i]
} else {
mu[i] <- beta1
}
y[i] ~ dnorm(mu[i], tau)
}
However, if-then is not part of the lanugage. Note that I'm not trying to incorporate an if-then based on estimated values of parameters. Rather I just want to have a script that can take flexible input.
Question
What is a good way to conditionally run parts of a JAGS script based on a user supplied variable?
Initial thoughts
- Put a macro name in the text and use a text replacement function in R like
gsub
to replace the macro name with the desired text. I guess this would work, but it seems like a bit of a hack. It would be nice to have everything inside the script.
Best Answer
Here is one example of implementing a basic macro substitution system for JAGS scripts.
Explanation of the system
textConnection
function for use with rjags.I like this system for a few reasons:
Example
Specifically, this example, aims to allow the user to fit a particular type of multilevel nonlinear model. It is designed to allow for three functional forms: a two parameter power, three parameter power, and a three parameter exponential.
The macro section structures macros as a list of lists. The top level list contains one element for each macro token. For each macro token, there is the macro token text, and the conditional replacement text.
Finally, a for loop applies all the macro replacements to the raw script.
See below (scrolling is required):
Demonstration
Thus, we can produce the processed JAGS model with
And if we want to view the resulting model, we can do
which results in