Translating Probability Density Functions: From R to BUGS and Back Again

Abstract:

The ability to implement statistical models in the BUGS language facilitates Bayesian inference by automating MCMC algorithms. Software packages that interpret the BUGS language include OpenBUGS, WinBUGS, and JAGS. R packages that link BUGS software to the R environment, including rjags and R2WinBUGS, are widely used in Bayesian analysis. Indeed, many packages in the Bayesian task view on CRAN (http://cran.r-project.org/web/views/Bayesian.html) depend on this integration. However, the R and BUGS languages use different representations of common probability density functions, creating a potential for errors to occur in the implementation or interpretation of analyses that use both languages. Here we review different parameterizations used by the R and BUGS languages, describe how to translate between the languages, and provide an R function, r2bugs.distributions, that transforms parameterizations from R to BUGS and back again.

Cite PDF Tweet

Published

June 17, 2013

Received

Feb 8, 2013

Citation

S. LeBauer, et al., 2013

Volume

Pages

5/1

207 - 209


Table 1: Summary of different parameterizations of common distributions used by R and BUGS. Note: For ease of reference, parameterizations follow the JAGS and R documentation; as a result, the table includes equivalent equations that appear different, either because JAGS and R use different names for the same parameter or because the equation has been rearranged. For example, the shape parameter of the Gamma distribution is r in the BUGS documentation and a in the R documentation. For the Binomial, Negative Binomial, and Gamma distributions, BUGS and R expect parameters in different order (the order of parameters matters since arguments are assigned based on position in BUGS and may be in R as well). R allows alternate parameterizations for the Negative Binomial and Gamma distributions, but these are not shown here. The variable x is implicit in all of the BUGS “Use” expressions. The Beta, Poisson, Exponential, and Uniform distributions have identical parameterizations in R and BUGS.
Distribution Lang. Parameterization Use Notes
Normal
R 12πσexp((xμ)22σ2) dnorm(x, mean =μ, sd =σ)
BUGS τ2πexp((xμ)2τ) dnorm(mean =μ, precision =τ) τ=(1σ)2
log-Normal
R 12πσxexp((log(x)μ)2(2σ2)) dlnorm(x, mean =μ, sd =σ)
BUGS τxexp(τ(log(x)μ)22) dlnorm(mean =μ, precision =τ) τ=(1σ)2
Binomial reverse parameter order
R (nx)px(1p)nx dbinom(x, size =n, prob =p)
BUGS same dbin(prob =p, size =n)
Negative Binomial reverse parameter order
R Γ(x+n)Γ(n)x!pn(1p)x dnbinom(x, size =n, prob =p) size (n) is continuous
BUGS (x+r1x)pr(1p)x dnegbin(prob =p, size =r) size (r) is discrete
Weibull
R ab(xb)a1exp((xb)a) dweibull(x, shape =a, scale =b)
BUGS νλxν1exp(λxν) dweib(shape =ν, lambda =λ) λ=(1b)a
Gamma reverse parameter order
R raΓ(a)xa1exp(xr) dgamma(x, shape =a, rate =r)
BUGS λrxr1exp(λx)Γ(r) dgamma(shape =r, lambda =λ)

1 Probability density functions in R and BUGS

R and BUGS implement many of the same probability distribution functions, but they often parameterize the same distribution differently (Table 1). Although these probability distribution functions are clearly described in the documentation of their respective languages, we were unable to find a summary of these differences in one place. The motivation for this article is to document and clarify these differences. Our sources are the JAGS documentation and the documentation of individual R functions.

2 A bilingual translation function

To support the automation of model specification in JAGS with priors computed and stored in R , we developed a function to translate parameterizations of common probability distributions from R to BUGS (and back again, by specifying direction = ’bugs2r’). Parameter transformations, parameter order, and differences in function names are documented in Table 1 and implemented in the R function r2bugs.distributions.

r2bugs.distributions <- function(priors, direction = 'r2bugs') {
  priors$distn  <- as.character(priors$distn)
  priors$parama <- as.numeric(priors$parama)
  priors$paramb <- as.numeric(priors$paramb)
  ## index dataframe according to distribution
  norm   <- priors$distn %in% c('norm', 'lnorm')    # these have same transform
  weib   <- grepl("weib", priors$distn)             # matches r and bugs version
  gamma  <- priors$distn == 'gamma'
  chsq   <- grepl("chisq", priors$distn)            # matches r and bugs version
  bin    <- priors$distn %in% c('binom', 'bin')     # matches r and bugs version
  nbin   <- priors$distn %in% c('nbinom', 'negbin') # matches r and bugs version
  
  ## Normal, log-Normal: Convert sd to precision
  exponent <- ifelse(direction == "r2bugs", -2, -0.5) 
  priors$paramb[norm] <-  priors$paramb[norm] ^ exponent
  
  ## Weibull
  if(direction == 'r2bugs'){
    ## Convert R parameter b to BUGS parameter lambda by l = (1/b)^a
    priors$paramb[weib] <- (1 / priors$paramb[weib]) ^ priors$parama[weib]
  } else if (direction == 'bugs2r') {
    ## Convert BUGS parameter lambda to BUGS parameter b by b = l^(-1/a)
    priors$paramb[weib] <-  priors$paramb[weib] ^ (- 1 / priors$parama[weib] ) 
  }
  
  ## Reverse parameter order for binomial and negative binomial
  priors[bin | nbin, c('parama', 'paramb')] <-
    priors[bin | nbin, c('paramb', 'parama')]
  
  ## Translate distribution names
  if(direction == "r2bugs"){
    priors$distn[weib] <- "weib"
    priors$distn[chsq] <- "chisqr"
    priors$distn[bin]  <- "bin"
    priors$distn[nbin] <- "negbin"
  } else if(direction == "bugs2r"){
    priors$distn[weib] <- "weibull"
    priors$distn[chsq] <- "chisq"
    priors$distn[bin]  <- "binom"
    priors$distn[nbin] <- "nbinom"
  }
  return(priors)
}

3 A simple example

As an example, we take the R-parameterized prior distribution XN(μ=10,σ=2) and convert it to BUGS parameterization XN(μ=10,τ=1/4). We specify a model in JAGS that allows us to sample directly from a prior distribution. The function works for each of the distributions in Table 1. This particular example is the JAGS implementation of rnorm(10000, 10, 2) in R. It is presented as minimal demonstration; for a non-trivial application, see .


r.distn <- data.frame(distn = "norm", parama = 10, paramb = 2)
bugs.distn <- r2bugs.distributions(r.distn)
   
sample.bugs.distn <- function(prior = data.frame(distn = "norm", parama = 0, 
                                paramb = 1), n = 10000) {
  require(rjags)
  model.string <- paste0(
    "model{Y ~ d", prior$distn, 
    "(", prior$parama, 
    ## chisqr has only one parameter
    ifelse(prior$distn == "chisqr", "", paste0(", ", prior$paramb)), ");",
    "a <- x}"
  )   
  ## trick JAGS into running without data  
  writeLines(model.string, con = "test.bug")
  j.model  <- jags.model(file = "test.bug", data = list(x = 1))
  mcmc.object <- window(
    coda.samples(
      model = j.model, variable.names = c('Y'), 
      n.iter = n * 4, thin = 2),
    start = n)
  Y <- sample(as.matrix(mcmc.object)[,"Y"], n)
}
X <- sample.bugs.distn(bugs.distn)

4 Acknowlegements

This collaboration began on the Cross Validated statistical forum (http://stats.stackexchange.com/q/5543/1381). Funding was provided to DSL and MCD by the Energy Biosciences Institute.


CRAN packages used

rjags, R2WinBUGS

CRAN Task Views implied by cited packages

Bayesian, Cluster, GraphicalModels, MixedModels

Note

This article is converted from a Legacy LaTeX article using the texor package. The pdf version is the official version. To report a problem with the html, refer to CONTRIBUTE on the R Journal homepage.

Footnotes

    References

    D. S. LeBauer, D. Wang, K. T. Richter, C. C. Davidson and M. C. Dietze. Facilitating feedbacks between field measurements and ecosystem models. Ecological Monographs, 83(2): 133–154, 2013. URL http://www.esajournals.org/doi/abs/10.1890/12-0137.1.
    M. Plummer. JAGS Version 3.1.0 user manual. 0–39, 2010. URL http://sourceforge.net/projects/mcmc-jags/.

    Reuse

    Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".

    Citation

    For attribution, please cite this work as

    S. LeBauer, et al., "Translating Probability Density Functions: From R to BUGS and Back Again", The R Journal, 2013

    BibTeX citation

    @article{RJ-2013-020,
      author = {S. LeBauer, David and C. Dietze, Michael and M. Bolker, Benjamin},
      title = {Translating Probability Density Functions: From R to BUGS and Back Again},
      journal = {The R Journal},
      year = {2013},
      note = {https://rjournal.github.io/},
      volume = {5},
      issue = {1},
      issn = {2073-4859},
      pages = {207-209}
    }