### Defines the class
#' Bayesian Cost-Effectiveness models in the presence of structural zeros
#'
#' Writes a model file encoding the distributional assumptions, calls JAGS in
#' background and perform the Bayesian analysis of the selected model.
#'
#'
#' @aliases bces0 bces0.default
#' @param data A named list including values for the variables e0 (measure of
#' effectiveness for the subjects in treatment arm t=0), e1 (effectiveness for
#' the subjects in t=1), c0 (individual costs in t=0), c1 (individual costs in
#' t=1), H.psi and H.zeta (vectors of fixed hyperparameters for the prior in
#' the positive cost groups. If only one value is passed as argument, then
#' BCEs0 assumes that this is to be used for both treatments being considered).
#' Additional optional elements are X0 (a matrix of covariates for t=0) and X1
#' (a matrix of covariates for t=1) that can be used to estimate the selection
#' model for null costs
#' @param dist.c A text string defining the selected distribution for the
#' costs. Available options are Gamma ("gamma"), log-Normal ("logn") and Normal
#' ("norm")
#' @param dist.e A text string defining the selected distribution for the
#' measure of effectiveness. Available options are Beta ("beta"), Gamma
#' ("gamma"), Bernoulli ("bern") and Normal ("norm")
#' @param w A parameter used to characterise the mean of the degenerate
#' distribution for the structural zeros (default = 0.000001)
#' @param W A parameter used to characterise the standard deviaiton of the
#' degenerate distribution for the structural zeros (default = 0.000001)
#' @param n.iter Number of iterations to be run in JAGS (default = 10000)
#' @param n.burnin Number of iterations to be used as burn-in for the MCMC
#' procedure (default = 5000)
#' @param n.chains Number of Markov chains to be run (default = 2)
#' @param robust A string indicating whether a robust model should be chosen
#' for the patter model. If TRUE (default), then the regression coefficients
#' are modelled using a Cauchy(0,2.5) distribution. If FALSE, then a vague
#' Normal prior is used
#' @param model.file A string with the name of the txt file to which the JAGS
#' code is saved. Default is model.txt.
#' @return An object containing the following elements \item{mod}{A "rjags"
#' objects with the results of the MCMC simulations run using JAGS}
#' \item{params}{A vector including the parameters being monitored}
#' \item{dataJags}{A list contaning the data needed to run the MCMC
#' simulations} \item{inits}{A function used to initialise the random nodes in
#' the model}
#' @author Gianluca Baio
#' @references Baio G. (2013). Bayesian models for cost-effectiveness analysis
#' in the presence of structural zero costs.
#' http://arxiv.org/pdf/1307.5243v1.pdf
#' @keywords JAGS Markov Chain Monte Carlo Bayesian models for
#' cost-effectiveness analysis
#' @examples
#'
#' data(acupuncture)
#' m <- bces0(data,dist.c="gamma",dist.e="beta",n.iter=1000,n.burnin=500,n.chains=2)
#' print(m)
#' plot(m)
#'
#' @export bces0
bces0 <- function(data,dist.c=c("gamma","logn","norm"),dist.e=c("beta","gamma","bern","norm"),
w=1e-6,W=1e-6,n.iter=10000,n.burnin=5000,n.chains=2,robust=TRUE,model.file="model.txt") UseMethod("bces0")
### Call to the actual function
bces0.default <- function(data,dist.c=c("gamma","logn","norm"),dist.e=c("beta","gamma","bern","norm"),
w=1e-6,W=1e-6,n.iter=10000,n.burnin=5000,n.chains=2,robust=TRUE,model.file="model.txt") {
# BCES0 - Bayesian cost-effectiveness analysis in the presence of structural zero costs
# Based on Baio (2013). Bayesian models for cost-effectiveness analysis in the presence
# of structural zeros.
#
# data is a named list including values for the following variables:
# e0,e1: measure of effectiveness for intervention t=0,1, respectively
# c0,c1: costs for intervention t=0,1, respectively
# X0,X1: design matrices to estimate the selection model for t=0,1, respectively
# BCES0 checks that these are centered, and if not does it
# NB: if X0 and X1 are null (no covariates), assumes a random effect model to
# estimate the individual probability of having zero costs
# H.psi,H.zeta: a vector of fixed hyperparameters for the prior in the positive cost groups.
# If only one value is passed as argument, then BCEs0 assumes that this is to
# be used for both treatments being considered
#
# The package implements the following models
# for costs: Gamma, Log-Normal - these are quite general and probably good enough
# to describe most real-life situations.
# Also considers a Normal model (generally not good, but possibly useful
# for transformed data
#
# for benefits: Beta (good to describe QALYs in a 1-year horizon)
# Gamma (good to describe QALYs in a longer horizon)
# Bernoulli (good to describe hard measures, such as death)
# Normal (probably not too generalisable, but could be used for continuous scales)
#
# for the pattern model: if covariates are observed, then runs a simple logistic regression
# to estimate the probability of observing zero costs. If no covariates are passed
# as data, then only uses the intercept (marginal probability, assuming no confounders)
#
# w,W parameters to characterise the degenerate distribution for the structural zeros.
# w is the mean and W is the standard deviation *on the natural scale* for this
# distribution. Default values are w=W=1e-6 (0.000001), which imply effectively a
# mean of 0 and no variability
#
# robust if TRUE (default) then implements a Cauchy prior for the pattern model coefficients
# if FALSE, then implements a vague Normal prior
#
# model.file string text with the name of the file to which the JAGS model code is saved. The
# default is "model.txt", but the user can choose a different string
#
# version 6 November 2013
## 0. Sets up the required path and libraries
if (!isTRUE(requireNamespace("R2jags", quietly = TRUE))) {
stop("You need to install the MCMC software 'JAGS' and the R package 'R2jags'.\nPlease see instructions at:\n'http://mcmc-jags.sourceforge.net/'\nand then run in your R terminal:\ninstall.packages('R2jags')")
}
working.dir <- getwd()
# checks that some covariates are available for the selection model
chk <- is.null(data$X0) & is.null(data$X1)
if (chk==TRUE) { # if not:
dist.d <- "int" # then uses only the intercept (Cauchy prior)
} else { # alternatively:
if (robust==TRUE) {
dist.d <- "cov.cauchy" # regression model with the covariates (Cauchy prior)
}
if (robust==FALSE) {
dist.d <- "cov.norm" # regression model with the covariates (Normal prior)
}
}
## Now runs JAGS with the required model
# 1. writes the model code to a file using the function "writeModel". This selects the
# required modules and then assign the name of the file to the variable "filein"
writeModel(dist.c,dist.e,dist.d,model.file)
filein <- model.file
# 2. Creates variables & check that all works out OK
d0 <- ifelse(data$c0==0,1,0) # indicator of null cost for t=0
d1 <- ifelse(data$c1==0,1,0) # indicator of null cost for t=1
n0 <- length(d0) # sample size for t=0
n1 <- length(d1) # sample size for t=1
# Creates copies of the cost variables to be used in the marginal model. For computational
# reasons, recodes zeros to a small, strictly positive value. But this has NO IMPACT
# whatsoever on the estimation of the costs, since the prior is extremely informative
# (and places all the mass on 0), so that the posterior is basically not affected from
# the observed data, for the subjects with observed null costs
c0.star <- data$c0; c0.star[d0==1] <- .0000001
c1.star <- data$c1; c1.star[d1==1] <- .0000001
# Defines the data list; this works directly if there are no covariates (sets
# parameters for Cauchy priors on the intercepts of the selection model)
dataJags <- list(n0=n0,n1=n1,d0=d0,d1=d1,m.beta0=0,Q.beta0=2.5^-2,m.beta1=0,
Q.beta1=2.5^-2,c0=data$c0,c1=data$c1,e0=data$e0,e1=data$e1,
H.psi=data$H.psi,H.zeta=data$H.zeta,w=w,W=W,c0.star=c0.star,c1.star=c1.star)
# If only one value is passed for H.psi, H.zeta, then uses that value for both treatments
if (length(data$H.psi)==1) {
dataJags$H.psi <- rep(data$H.psi,2)
}
if (length(data$H.zeta)==1) {
dataJags$H.zeta <- rep(data$H.psi,2)
}
# Specifies the number of covariates (in the intercept-only case, ie 1)
if (chk==TRUE) {dataJags$J <- 1} # needs to specify the number of covariates
# if none, then J=1 (only the intercept)
# Do this only if there are some "true" covariates (in addition to the intercept)
if (chk==FALSE) {
# first checks that the design matrices have a column of 1s (for the intercept)
if (any(data$X0[,1]!=1)==TRUE) {
data$X0 <- cbind(rep(1,dim(data$X0)[1]),data$X0) # if not, adds it
}
if (any(data$X1[,1]!=1)==TRUE) {
data$X1 <- cbind(rep(1,dim(data$X1)[1]),data$X1) # if not, adds it
}
# sets the number of covariates in the pattern model (including the intercept)
J <- dim(data$X0)[2]
# then checks that the covariates are centered and if not does it
threshold <- 1e-12 # if within this threshold to 0 then effectively 0
Z0 <- data$X0; Z1 <- data$X1
for (j in 2:J) {
if (mean(data$X0[,j])>threshold) {
Z0[,j] <- scale(data$X0[,j],scale=FALSE)
}
if (mean(data$X1[,j])>threshold) {
Z1[,j] <- scale(data$X1[,j],scale=FALSE)
}
}
# Finally modifies the data list to include the covariates as well
dataJags$J <- J
dataJags$Z0 <- Z0
dataJags$Z1 <- Z1
if (robust==FALSE) {
dataJags$m.beta0 <- rep(0,J) # m.beta0=Normal mean vector
dataJags$m.beta1 <- rep(0,J) # m.beta1=Normal mean vector
dataJags$Q.beta0 <- .00001*diag(J) # Q.beta0=Normal precision matrix
dataJags$Q.beta1 <- .00001*diag(J) # Q.beta1=Normal precision matrix
}
}
# 3. Defines the parameters vector
params <- c("p","mu.c","mu.e","eta0[1]","lambda0[1]","eta1[1]","lambda1[1]",
"beta0","beta1","gamma0","gamma1","psi0","psi1")
# the parameters tau0,tau1 are only relevant if benefits are not modelled as Bernoulli
if (dist.e!="bern") {
params <- c(params,c("tau0","tau1"))
}
# 4. Defines the initial values for the random nodes in the model
# NB This is a general structure that works for all the model implemented
list.temp <- list(
beta0=rnorm(dataJags$J,0,1),beta1=rnorm(dataJags$J,0,1),psi0=c(runif(1),NA),
psi1=c(runif(1),NA),zeta0=c(runif(1),NA),zeta1=c(runif(1),NA),log.tau0=runif(1),
xi0=runif(1),log.tau1=runif(1),xi1=runif(1)
)
inits <- function(){
list.temp
}
# 5. Runs JAGS to produce the posterior distributions
n.iter <- n.iter # number of iterations
n.burnin <- n.burnin # number of burn-in
n.thin <- floor((n.iter-n.burnin)/500) # thinning so that 1000 iterations are stored
n.chains <- n.chains # number of Markov chains
mod <- R2jags::jags(dataJags, inits, params, model.file=model.file,
n.chains=n.chains, n.iter, n.burnin, n.thin,
DIC=TRUE, working.directory=working.dir, progress.bar="text")
# 6. Defines the output of the function
out <- list(mod=mod,params=params,dataJags=dataJags,inits=inits)
class(out) <- "bces0"
out
}
#####
## Print method for objects in the class bces0
#' Print method for objects in the class "bces0"
#'
#' Specific method for objects in the class BCEs0
#'
#' Returns a summary table with selected statistics for all the nodes in the
#' model that can be used to assess convergence
#'
#' @param x The object in the class "BCEs0" obtained by calling the function
#' bces0
#' @param ... Additional arguments affecting the summary produced
#' @author Gianluca Baio
#' @seealso \code{\link{bces0}}
#' @references Baio G. (2013). Bayesian models for cost-effectiveness analysis
#' in the presence of structural zero costs.
#' http://arxiv.org/pdf/1307.5243v1.pdf
#' @keywords JAGS Markov Chain Monte Carlo Bayesian models for
#' cost-effectiveness analysis
#' @examples
#'
#' ## To be added here
#'
#' @export print.bces0
print.bces0 <- function(x,...){
print(x$mod,interval=c(.025,.975),digit=3) # prints the summary results
}
#####
## Traceplot method for objects in the class bces0
#' Plot method for objects in the class "bces0"
#'
#' Produces a traceplot for the main nodes in the model
#'
#' Returns a traceplot to assess convergence
#'
#' @param x The object in the class "BCEs0" obtained by calling the function
#' bces0
#' @param ... Additional arguments affecting the summary produced
#' @author Gianluca Baio
#' @seealso \code{\link{bces0}}
#' @references Baio G. (2013). Bayesian models for cost-effectiveness analysis
#' in the presence of structural zero costs.
#' http://arxiv.org/pdf/1307.5243v1.pdf
#' @keywords JAGS Markov Chain Monte Carlo Bayesian models for
#' cost-effectiveness analysis
#' @examples
#'
#' ## To be added here
#'
#' @export plot.bces0
plot.bces0 <- function(x,...){
col <- colors()
mdl <- x$mod$BUGSoutput
n.chains <- x$mod$BUGSoutput$n.chains
nodes.to.plot <- c("mu.c[1]","mu.c[2]","mu.e[1]","mu.e[2]","p[1]","p[2]")
xlab <- "Iteration"
ylab <- ""
par(mfrow=c(3,2))
if (n.chains==1) {
plot(mdl$sims.array[,1,nodes.to.plot[1]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",mu[c0])))
plot(mdl$sims.array[,1,nodes.to.plot[2]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",mu[c1])))
plot(mdl$sims.array[,1,nodes.to.plot[3]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",mu[e0])))
plot(mdl$sims.array[,1,nodes.to.plot[4]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",mu[e1])))
plot(mdl$sims.array[,1,nodes.to.plot[5]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",p[0])))
plot(mdl$sims.array[,1,nodes.to.plot[6]],col="blue",t="l",
xlab=xlab,ylab=ylab,main=expression(paste("Traceplot for ",p[1])))
}
if (mdl$n.chains>=2) {
cols <- c("blue","red","green","magenta","orange","brown","azure")
plot(mdl$sims.array[,1,nodes.to.plot[1]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",mu[c0])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[1]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[1]],t="l",col=col[which(col==cols[2])])
}
plot(mdl$sims.array[,1,nodes.to.plot[2]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",mu[c1])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[2]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[2]],t="l",col=col[which(col==cols[2])])
}
plot(mdl$sims.array[,1,nodes.to.plot[3]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",mu[e0])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[3]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[3]],t="l",col=col[which(col==cols[2])])
}
plot(mdl$sims.array[,1,nodes.to.plot[4]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",mu[e1])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[4]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[4]],t="l",col=col[which(col==cols[2])])
}
plot(mdl$sims.array[,1,nodes.to.plot[5]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",p[0])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[5]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[5]],t="l",col=col[which(col==cols[2])])
}
plot(mdl$sims.array[,1,nodes.to.plot[6]],t="l",
col=col[which(col==cols[1])],xlab=xlab,ylab=ylab,
main=expression(paste("Traceplot for ",p[1])),
ylim=range(mdl$sims.array[,1:2,nodes.to.plot[6]]))
for (i in 2:mdl$n.chains) {
points(mdl$sims.array[,2,nodes.to.plot[6]],t="l",col=col[which(col==cols[2])])
}
}
}
#####
#' writeModel
#'
#' This function selects suitable bits of JAGS code to build the model file
#' encoding the selected distributional assumptions for the cost and
#' effectiveness variables (and for the selection model)
#'
#'
#' @param dist.c A text string defining the selected distribution for the
#' costs. Available options are Gamma ("gamma"), log-Normal ("logn") and Normal
#' ("norm")
#' @param dist.e A text string defining the selected distribution for the
#' measure of effectiveness. Available options are Beta ("beta"), Gamma
#' ("gamma"), Bernoulli ("bern") and Normal ("norm")
#' @param dist.d A text string defining the selection model. Possible choices
#' are "cov.cauchy" or "cov.norm" (used when individual covariates are
#' available and can be used to estimate the probability of zero costs) and
#' "int" (when no covariate is available and an intercept-only model is
#' fitted). The function writes a text file in the current working directory,
#' including the relevant bits of code, that can be then passed to the call to
#' the function jags to run the MCMC simulations in background
#' @param model.file A string with the name of the model file to which the JAGS
#' code is saved
#' @return Writes out the file with the selected distributional assumptions to
#' the file "model.txt" in the current working directory
#' @author Gianluca Baio
#' @seealso \code{\link{bces0}}
#' @references Baio G. (2013). Bayesian models for cost-effectiveness analysis
#' in the presence of structural zero costs.
#' http://arxiv.org/pdf/1307.5243v1.pdf
#' @keywords JAGS Bayesian models
#' @examples
#'
#' ## To be added here
#'
#' @export writeModel
writeModel <- function(dist.c,dist.e,dist.d,model.file) {
## Selects the modules in the model code, according to the distributional assumptions
## 1. Selection model
## a. Standard regression as a function of the observed covariates X0,X1 (Normal prior)
sel.mod.cov.norm <- "
model {
# 1. Pattern model for c=0 (Normal prior)
# a. Intervention t=0
for (i in 1:n0) {
d0[i] ~ dbern(pi0.hat[i])
pi0.hat[i] <- max(.00001,min(.99999,pi0[i]))
logit(pi0[i]) <- Z0[i,]%*%beta0
}
# b. Intervention t=1
for (i in 1:n1) {
d1[i] ~ dbern(pi1.hat[i])
pi1.hat[i] <- max(.00001,min(.99999,pi1[i]))
logit(pi1[i]) <- Z1[i,]%*%beta1
}
# c. Priors on the regression coefficients
beta0[1:J] ~ dmnorm(m.beta0[],Q.beta0[,])
beta1[1:J] ~ dmnorm(m.beta1[],Q.beta1[,])
# d. Average probability of zero cost
p[1] <- exp(beta0[1])/(1+exp(beta0[1])) # intervention t=0
p[2] <- exp(beta1[1])/(1+exp(beta1[1])) # intervention t=1
"
## b. Standard regression as a function of the observed covariates X0,X1 (Cauchy prior)
sel.mod.cov.cauchy <- "
model {
# 1. Pattern model for c=0 (Cauchy prior)
# a. Intervention t=0
for (i in 1:n0) {
d0[i] ~ dbern(pi0.hat[i])
pi0.hat[i] <- max(.00001,min(.99999,pi0[i]))
logit(pi0[i]) <- Z0[i,]%*%beta0
}
# b. Intervention t=1
for (i in 1:n1) {
d1[i] ~ dbern(pi1.hat[i])
pi1.hat[i] <- max(.00001,min(.99999,pi1[i]))
logit(pi1[i]) <- Z1[i,]%*%beta1
}
# c. Priors on the regression coefficients
for (j in 1:J) {
beta0[j] ~ dt(m.beta0,Q.beta0,1)
beta1[j] ~ dt(m.beta1,Q.beta1,1)
}
# beta0[1:J] ~ dmt(m.beta0[],Q.beta0[,],1)
# beta1[1:J] ~ dmt(m.beta1[],Q.beta1[,],1)
# d. Average probability of zero cost
p[1] <- exp(beta0[1])/(1+exp(beta0[1])) # intervention t=0
p[2] <- exp(beta1[1])/(1+exp(beta1[1])) # intervention t=1
"
## c. Intercept-only model (when no covariates are available)
sel.mod.int <- "
model {
# 1. Pattern model for c=0 (intercept-only, Cauchy priors)
# a. Intervention t=0
for (i in 1:n0) {
d0[i] ~ dbern(pi0.hat[i])
pi0.hat[i] <- max(.00001,min(.99999,pi0[i]))
logit(pi0[i]) <- beta0 #u0[i]
# u0[i] ~ dnorm(beta0,tau.u0) # individual random effect
}
# b. Intervention t=1
for (i in 1:n1) {
d1[i] ~ dbern(pi1.hat[i])
pi1.hat[i] <- max(.00001,min(.99999,pi1[i]))
logit(pi1[i]) <- beta1
}
# c. Priors on the regression coefficients
# NB: uses a Cauchy(0,2.5) distribution to stabilise the intercept
beta0[J] ~ dt(m.beta0,Q.beta0,1)
beta1[J] ~ dt(m.beta1,Q.beta1,1)
# d. Average probability of zero cost
p[1] <- exp(beta0[1])/(1+exp(beta0[1])) # intervention t=0
p[2] <- exp(beta1[1])/(1+exp(beta1[1])) # intervention t=1
"
## 2. Marginal model for the costs
## a. Gamma specification
marg.cost.gamma <- "
# 2. Marginal model for the costs
# a. Intervention t=0
for (i in 1:n0) {
c0.star[i] ~ dgamma(eta0[(d0[i]+1)],lambda0[(d0[i]+1)])
}
# Defines the shape parameters for the two components of the mixture
for (s in 1:2) {
eta0[s] <- psi0[s]*lambda0[s]
lambda0[s] <- psi0[s]/pow(zeta0[s],2)
}
# b. Intervention t=1
for (i in 1:n1) {
c1.star[i] ~ dgamma(eta1[(d1[i]+1)],lambda1[(d1[i]+1)])
}
# Defines the shape parameters for the two components of the mixture
for (s in 1:2) {
eta1[s] <- psi1[s]*lambda1[s]
lambda1[s] <- psi1[s]/pow(zeta1[s],2)
}
# Priors on the natural scale parameters
psi0[1] ~ dunif(0,H.psi[1]); zeta0[1] ~ dunif(0,H.zeta[1])
psi0[2] <- w; zeta0[2] <- W
psi1[1] ~ dunif(0,H.psi[2]); zeta1[1] ~ dunif(0,H.zeta[2])
psi1[2] <- w; zeta1[2] <- W
# Weights the cost components by the probability of null costs
mu.c[1] <- p[1]*psi0[2] + (1-p[1])*psi0[1]
mu.c[2] <- p[2]*psi1[2] + (1-p[2])*psi1[1]
"
## b. log-Normal specification
marg.cost.logn <- "
# 2. Marginal model for the costs
# a. Intervention t=0
for (i in 1:n0) {
c0.star[i] ~ dlnorm(eta0[(d0[i]+1)],inv.lambda0[(d0[i]+1)])
}
# Defines the mean and variance on the log-cost scale for the two components of the mixture
for (s in 1:2) {
eta0[s] <- log(psi0[s])-.5*log(1+pow(zeta0[s]/psi0[s],2))
lambda0[s] <- pow(log(1+pow(zeta0[s]/psi0[s],2)),.5)
inv.lambda0[s] <- pow(lambda0[s],-2)
}
# b. Intervention t=1
for (i in 1:n1) {
c1.star[i] ~ dlnorm(eta1[(d1[i]+1)],inv.lambda1[(d1[i]+1)])
}
# Defines the mean and variance on the log-cost scale for the two components of the mixture
for (s in 1:2) {
eta1[s] <- log(psi1[s])-.5*log(1+pow(zeta1[s]/psi1[s],2))
lambda1[s] <- pow(log(1+pow(zeta1[s]/psi1[s],2)),.5)
inv.lambda1[s] <- pow(lambda1[s],-2)
}
# Priors on the natural scale parameters
psi0[1] ~ dunif(0,H.psi[1])
zeta0[1] ~ dunif(0,H.zeta[1])
psi0[2] <- w
zeta0[2] <- W
psi1[1] ~ dunif(0,H.psi[2])
zeta1[1] ~ dunif(0,H.zeta[2])
psi1[2] <- w
zeta1[2] <- W
# Weights the average by the probability of null costs
mu.c[1] <- p[1]*psi0[2] + (1-p[1])*psi0[1]
mu.c[2] <- p[2]*psi1[2] + (1-p[2])*psi1[1]
"
## c. Normal specification
marg.cost.norm <- "
# 2. Marginal model for the costs
# a. Intervention t=0
for (i in 1:n0) {
c0[i] ~ dnorm(eta0[(d0[i]+1)],inv.lambda0[(d0[i]+1)])
c0.star[i] ~ dnorm(0,0.00001) # for consistency only --- not used!
}
# Defines the mean and variance on the log-cost scale for the two components of the mixture
for (s in 1:2) {
eta0[s] <- psi0[s]
lambda0[s] <- zeta0[s]
inv.lambda0[s] <- pow(lambda0[s],-2)
}
# b. Intervention t=1
for (i in 1:n1) {
c1[i] ~ dnorm(eta1[(d1[i]+1)],inv.lambda1[(d1[i]+1)])
c1.star[i] ~ dnorm(0,0.00001) # for consistency only --- not used!
}
# Defines the mean and variance on the log-cost scale for the two components of the mixture
for (s in 1:2) {
eta1[s] <- psi1[s]
lambda1[s] <- zeta1[s]
inv.lambda1[s] <- pow(lambda1[s],-2)
}
# Priors on the natural scale parameters
psi0[1] ~ dunif(0,H.psi[1])
zeta0[1] ~ dunif(0,H.zeta[1])
psi0[2] <- w
zeta0[2] <- W
psi1[1] ~ dunif(0,H.psi[2])
zeta1[1] ~ dunif(0,H.zeta[2])
psi1[2] <- w
zeta1[2] <- W
# Weights the average by the probability of null costs
mu.c[1] <- p[1]*psi0[2] + (1-p[1])*psi0[1]
mu.c[2] <- p[2]*psi1[2] + (1-p[2])*psi1[1]
"
## 3. Conditional model for the effectiveness
## a. Beta specification
cond.eff.beta <- "
# 3. Conditional model for the benefits
# a. Intervention t=0
for (i in 1:n0) {
e0[i] ~ dbeta(phi0[i]*tau0,(1-phi0[i])*tau0)
logit(phi0[i]) <- xi0 + gamma0*(c0[i]-mu.c[1])
}
gamma0 ~ dnorm(0,0.0001)
log.tau0 ~ dnorm(0,0.0001)
tau0 <- exp(log.tau0)
xi0 ~ dnorm(0,0.0001)
mu.e[1] <- exp(xi0)/(1+exp(xi0))
# b. Intervention t=1
for (i in 1:n1) {
e1[i] ~ dbeta(phi1[i]*tau1,(1-phi1[i])*tau1)
logit(phi1[i]) <- xi1 + gamma1*(c1[i]-mu.c[2])
}
gamma1 ~ dnorm(0,0.0001)
log.tau1 ~ dnorm(0,0.0001)
tau1 <- exp(log.tau1)
xi1 ~ dnorm(0,0.0001)
mu.e[2] <- exp(xi1)/(1+exp(xi1))
}
"
## b. Normal specification
cond.eff.norm <- "
# 3. Conditional model for the benefits
# a. Intervention t=0
for (i in 1:n0) {
e0[i] ~ dnorm(phi0[i],tau0)
phi0[i] <- xi0 + gamma0*(c0[i]-mu.c[1])
}
gamma0 ~ dnorm(0,0.0001)
log.tau0 ~ dnorm(0,0.0001)
tau0 <- exp(log.tau0)
xi0 ~ dnorm(0,0.0001)
mu.e[1] <- xi0
# b. Intervention t=1
for (i in 1:n1) {
e1[i] ~ dnorm(phi1[i],tau1)
phi1[i] <- xi1 + gamma1*(c1[i]-mu.c[2])
}
gamma1 ~ dnorm(0,0.0001)
log.tau1 ~ dnorm(0,0.0001)
tau1 <- exp(log.tau1)
xi1 ~ dnorm(0,0.0001)
mu.e[2] <- xi1
}
"
## c. Gamma specification
cond.eff.gamma <- "
# 3. Conditional model for the benefits
# a. Intervention t=0
for (i in 1:n0) {
e0[i] ~ dgamma(tau0,kappa0[i])
kappa0[i] <- tau0/phi0[i]
phi0[i] <- xi0 + gamma0*(c0[i]-mu.c[1])
}
gamma0 ~ dnorm(0,0.0001)
log.tau0 ~ dnorm(0,0.0001)
tau0 <- exp(log.tau0)
xi0 ~ dnorm(0,0.0001)
mu.e[1] <- xi0
# b. Intervention t=1
for (i in 1:n1) {
e1[i] ~ dgamma(tau1,kappa1[i])
kappa1[i] <- tau1/phi1[i]
phi1[i] <- xi1 + gamma1*(c1[i]-mu.c[2])
}
gamma1 ~ dnorm(0,0.0001)
log.tau1 ~ dnorm(0,0.0001)
tau1 <- exp(log.tau1)
xi1 ~ dnorm(0,0.0001)
mu.e[2] <- xi1
}
"
## d. Bernoulli specification
cond.eff.bern <- "
# 3. Conditional model for the benefits
# a. Intervention t=0
for (i in 1:n0) {
e0[i] ~ dbern(phi0[i])
logit(phi0[i]) <- xi0 + gamma0*(c0[i]-mu.c[1])
}
gamma0 ~ dnorm(0,0.0001)
log.tau0 ~ dnorm(0,0.0001) # not really needed in this model, but kept for simplicity
xi0 ~ dnorm(0,0.0001)
mu.e[1] <- exp(xi0)/(1+exp(xi0))
# b. Intervention t=1
for (i in 1:n1) {
e1[i] ~ dbern(phi1[i])
logit(phi1[i]) <- xi1 + gamma1*(c1[i]-mu.c[2])
}
gamma1 ~ dnorm(0,0.0001)
log.tau1 ~ dnorm(0,0.0001) # not really needed in this model, but kept for simplicity
xi1 ~ dnorm(0,0.0001)
mu.e[2] <- exp(xi1)/(1+exp(xi1))
}
"
## Combines the required modules in a single model code
mod.sel <- c("cov.cauchy","cov.norm","int")
mod.cost <- c("gamma","logn","norm")
mod.eff <- c("beta","norm","gamma","bern")
lab.sel <- c("Model with covariates (Cauchy prior)","Model with covariates (Normal prior)",
"Model with intercept only")
lab.cost <- c("Gamma","Log-Normal","Normal")
lab.eff <- c("Beta","Normal","Gamma","Bernoulli")
model <- NULL # avoids a NOTE when checking the package
for (ms in 1:length(mod.sel)) {
for (mc in 1:length(mod.cost)) {
for (me in 1:length(mod.eff)) {
if (dist.d==mod.sel[ms] & dist.c==mod.cost[mc] & dist.e==mod.eff[me]) {
summary.text <- paste0("# ",lab.cost[mc]," marginal model for the cost, ",lab.eff[me],
" conditional model for effectiveness\n")
txt <- paste0("summary.text,sel.mod.",mod.sel[ms],",marg.cost.",
mod.cost[mc],",cond.eff.",mod.eff[me])
cmd <- paste0("model <- paste(",txt,")")
eval(parse(text=cmd))
}
}
}
}
filein <- model.file
writeLines(model,con=filein)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.