# OneOddGroupModelComp2E.R
# Accompanies the book:
# Kruschke, J. K. (2014). Doing Bayesian Data Analysis:
# A Tutorial with R, JAGS, and Stan. 2nd Edition. Academic Press / Elsevier.
#graphics.off()
#rm(list=ls(all=TRUE))
#source("DBDA2E-utilities.R")
#require(rjags)
#require(runjags)
#fileNameRoot="OneOddGroupModelComp2E-"
genMCMC.OneOddGroupModelComp2E <- function(object,
adaptSteps = 1000, # Number of steps to "tune" the samplers.
burnInSteps = 5000, # Number of steps to "burn-in" the samplers.
nChains = 3, # Number of chains to run.
numSavedSteps = 12000, # Total number of steps in chains to save.
thinSteps = 20, # Number of steps to "thin" (1=keep every step).
model = c("default", "group1"),
returnDataList = FALSE)
{
model <- match.arg(model)
#------------------------------------------------------------------------------
# THE DATA.
# Randomly generated fictitious data.
# For each subject, specify the condition s/he was in,
# the number of trials s/he experienced, and the number correct.
npg = 20 # number of subjects per group
ntrl = 20 # number of trials per subject
CondOfSubj = c( rep(1,npg) , rep(2,npg) , rep(3,npg) , rep(4,npg) )
nTrlOfSubj = rep( ntrl , 4*npg )
set.seed(47405)
condMeans = c(.40,.50,.51,.52)
nCorrOfSubj = c( rbinom(npg,ntrl,condMeans[1]) , rbinom(npg,ntrl,condMeans[2]) ,
rbinom(npg,ntrl,condMeans[3]) , rbinom(npg,ntrl,condMeans[4]) )
nCond = length(unique(CondOfSubj))
nSubj = length(CondOfSubj)
# jitter the data to be as close as possible to desired condition means:
for ( cIdx in 1:nCond ) {
nToAdd = round(condMeans[cIdx]*npg*ntrl)-sum(nCorrOfSubj[CondOfSubj==cIdx])
if ( nToAdd > 0 ) {
for ( i in 1:nToAdd ) {
thisNcorr = ntrl
while ( thisNcorr == ntrl ) {
randSubjIdx = sample(which(CondOfSubj==cIdx),size=1)
thisNcorr = nCorrOfSubj[randSubjIdx]
}
nCorrOfSubj[randSubjIdx] = nCorrOfSubj[randSubjIdx]+1
}
}
if ( nToAdd < 0 ) {
for ( i in 1:abs(nToAdd) ) {
thisNcorr = 0
while ( thisNcorr == 0 ) {
randSubjIdx = sample(which(CondOfSubj==cIdx),size=1)
thisNcorr = nCorrOfSubj[randSubjIdx]
}
nCorrOfSubj[randSubjIdx] = nCorrOfSubj[randSubjIdx]-1
}
}
}
#show( aggregate( nCorrOfSubj , by=list(CondOfSubj) , FUN=mean ) / ntrl )
# Package the data:
dataList = list(
nCond = nCond ,
nSubj = nSubj ,
CondOfSubj = CondOfSubj ,
nTrlOfSubj = nTrlOfSubj ,
nCorrOfSubj = nCorrOfSubj
)
if(returnDataList) {
return(dataList)
}
#------------------------------------------------------------------------------
# THE MODEL.
modelString = paste("
model {
for ( s in 1:nSubj ) {
nCorrOfSubj[s] ~ dbin( theta[s] , nTrlOfSubj[s] )
theta[s] ~ dbeta( aBeta[CondOfSubj[s]] , bBeta[CondOfSubj[s]] )
}
",
switch(model,
"group1" = "
for ( j in 1:nCond ) {
# Use omega[j] for model index 1, omega0 for model index 2:
aBeta[j] <- ( equals(mdlIdx,1)*omega[j]
+ equals(mdlIdx,2)*omega0 ) * (kappa[j]-2)+1
bBeta[j] <- ( 1 - ( equals(mdlIdx,1)*omega[j]
+ equals(mdlIdx,2)*omega0 ) ) * (kappa[j]-2)+1
}
for ( j in 1:2 ) {
omega[j] ~ dbeta( a[j,mdlIdx] , b[j,mdlIdx] )
}
omega[3] <- omega[2]
omega[4] <- omega[2]
",
"default" = "
for ( j in 1:nCond ) {
# Use omega[j] for model index 1, omega0 for model index 2:
aBeta[j] <- ( equals(mdlIdx,1)*omega[j]
+ equals(mdlIdx,2)*omega0 ) * (kappa[j]-2)+1
bBeta[j] <- ( 1 - ( equals(mdlIdx,1)*omega[j]
+ equals(mdlIdx,2)*omega0 ) ) * (kappa[j]-2)+1
omega[j] ~ dbeta( a[j,mdlIdx] , b[j,mdlIdx] )
}
",
stop()),
"
omega0 ~ dbeta( a0[mdlIdx] , b0[mdlIdx] )
for ( j in 1:nCond ) {
kappa[j] <- kappaMinusTwo[j] + 2
kappaMinusTwo[j] ~ dgamma( 2.618 , 0.0809 ) # mode 20 , sd 20
}
# Constants for prior and pseudoprior:
aP <- 1
bP <- 1
# a0[model] and b0[model]
a0[1] <- .48*500 # pseudo
b0[1] <- (1-.48)*500 # pseudo
a0[2] <- aP # true
b0[2] <- bP # true
# a[condition,model] and b[condition,model]
a[1,1] <- aP # true
a[2,1] <- aP # true
a[3,1] <- aP # true
a[4,1] <- aP # true
b[1,1] <- bP # true
b[2,1] <- bP # true
b[3,1] <- bP # true
b[4,1] <- bP # true
a[1,2] <- .40*125 # pseudo
a[2,2] <- .50*125 # pseudo
a[3,2] <- .51*125 # pseudo
a[4,2] <- .52*125 # pseudo
b[1,2] <- (1-.40)*125 # pseudo
b[2,2] <- (1-.50)*125 # pseudo
b[3,2] <- (1-.51)*125 # pseudo
b[4,2] <- (1-.52)*125 # pseudo
# Prior on model index:
mdlIdx ~ dcat( modelProb[] )
modelProb[1] <- .5
modelProb[2] <- .5
}
") # close quote for modelstring
writeLines( modelString , con="TEMPmodel.txt" )
#------------------------------------------------------------------------------
# INTIALIZE THE CHAINS.
# Let JAGS do it...
#------------------------------------------------------------------------------
# RUN THE CHAINS.
parameters = c("omega","kappa","omega0","theta","mdlIdx")
# nPerChain = ceiling( ( numSavedSteps * thinSteps ) / nChains ) # Steps per chain.
# # Create, initialize, and adapt the model:
# jagsModel = jags.model( "TEMPmodel.txt" , data=dataList , # inits=initsList ,
# n.chains=nChains , n.adapt=adaptSteps )
# # Burn-in:
# cat( "Burning in the MCMC chain...\n" )
# update( jagsModel , n.iter=burnInSteps )
# # The saved MCMC chain:
# cat( "Sampling final MCMC chain...\n" )
# codaSamples = coda.samples( jagsModel , variable.names=parameters ,
# n.iter=nPerChain , thin=thinSteps )
runJagsOut <- run.jags( method=c("rjags","parallel")[2] ,
model="TEMPmodel.txt" ,
monitor=parameters ,
data=dataList ,
#inits=initsList ,
n.chains=nChains ,
adapt=adaptSteps ,
burnin=burnInSteps ,
sample=ceiling(numSavedSteps/nChains) ,
thin=thinSteps ,
summarise=FALSE ,
plots=FALSE )
codaSamples = as.mcmc.list( runJagsOut )
# resulting codaSamples object has these indices:
# codaSamples[[ chainIdx ]][ stepIdx , paramIdx ]
#save( codaSamples , file=paste0(fileNameRoot,"Mcmc.Rdata") )
return(codaSamples)
}
#-------------------------------------------------------------------------------
# Display diagnostics of chain:
#parameterNames = varnames(codaSamples) # get all parameter names
#show(parameterNames)
#for ( parName in c("mdlIdx","omega[1]","omega0","kappa[1]","theta[1]") ) {
# diagMCMC( codaSamples , parName=parName ,
# saveName=fileNameRoot , saveType="eps" )
#}
#------------------------------------------------------------------------------
# EXAMINE THE RESULTS.
plotMCMC.OneOddGroupModelComp2E = function(object, codaSamples)
{
mcmcMat = as.matrix(codaSamples,chains=TRUE)
xLim=c(0.35,0.75)
# Display the model index
modelIdxSample = mcmcMat[, "mdlIdx" ]
pM1 = sum( modelIdxSample == 1 ) / length( modelIdxSample )
pM2 = 1 - pM1
string1 =paste("p( Diff Omega M1 | D )=",round(pM1,3),sep="")
string2 =paste("p( Same Omega M2 | D )=",round(pM2,3),sep="")
openGraph(10,4)
nStepsToPlot = 1000
plot( 1:nStepsToPlot , modelIdxSample[1:nStepsToPlot] , type="l" , lwd=2 ,
xlab="Step in Markov chain" , ylab="Model Index (1, 2)" ,
main=paste(string1,", ",string2,sep="") , col="skyblue" )
#saveGraph(file=paste0(fileNameRoot,"MdlIdx"),type="eps")
# Display the omega0 posterior
omega0sampleM1 = mcmcMat[, "omega0" ][ modelIdxSample == 1 ]
omega0sampleM2 = mcmcMat[, "omega0" ][ modelIdxSample == 2 ]
openGraph()
layout( matrix(1:2,nrow=2) )
plotPost( omega0sampleM1 , main="Pseudoprior for M = 1 (Diff Omega)" ,
xlab=expression(omega[0]) , xlim=xLim )
plotPost( omega0sampleM2 , main="Posterior for M = 2 (Same Omega)" ,
xlab=expression(omega[0]) , xlim=xLim )
#saveGraph(file=paste0(fileNameRoot,"Omega0"),type="eps")
# Display the omega[j] posterior
omega1sampleM1 = mcmcMat[, "omega[1]" ][ modelIdxSample == 1 ]
omega2sampleM1 = mcmcMat[, "omega[2]" ][ modelIdxSample == 1 ]
omega3sampleM1 = mcmcMat[, "omega[3]" ][ modelIdxSample == 1 ]
omega4sampleM1 = mcmcMat[, "omega[4]" ][ modelIdxSample == 1 ]
omega1sampleM2 = mcmcMat[, "omega[1]" ][ modelIdxSample == 2 ]
omega2sampleM2 = mcmcMat[, "omega[2]" ][ modelIdxSample == 2 ]
omega3sampleM2 = mcmcMat[, "omega[3]" ][ modelIdxSample == 2 ]
omega4sampleM2 = mcmcMat[, "omega[4]" ][ modelIdxSample == 2 ]
openGraph(10,5)
layout( matrix(1:8,nrow=2,byrow=T) )
plotPost( omega1sampleM1 , main="Posterior for M = 1 (Diff Omega)" ,
xlab=expression(omega[1]) , xlim=xLim )
plotPost( omega2sampleM1 , main="Posterior for M = 1 (Diff Omega)" ,
xlab=expression(omega[2]) , xlim=xLim )
plotPost( omega3sampleM1 , main="Posterior for M = 1 (Diff Omega)" ,
xlab=expression(omega[3]) , xlim=xLim )
plotPost( omega4sampleM1 , main="Posterior for M = 1 (Diff Omega)" ,
xlab=expression(omega[4]) , xlim=xLim )
plotPost( omega1sampleM2 , main="Pseudoprior for M = 2 (Same Omega)" ,
xlab=expression(omega[1]) , xlim=xLim )
plotPost( omega2sampleM2 , main="Pseudoprior for M = 2 (Same Omega)" ,
xlab=expression(omega[2]) , xlim=xLim )
plotPost( omega3sampleM2 , main="Pseudoprior for M = 2 (Same Omega)" ,
xlab=expression(omega[3]) , xlim=xLim )
plotPost( omega4sampleM2 , main="Pseudoprior for M = 2 (Same Omega)" ,
xlab=expression(omega[4]) , xlim=xLim )
#saveGraph(file=paste0(fileNameRoot,"OmegaCond"),type="eps")
# Display the differences of omega[j]'s
omegaSample = rbind( omega1sampleM1 , omega2sampleM1 , omega3sampleM1 , omega4sampleM1 )
openGraph(10,5)
layout( matrix(1:6,nrow=2,ncol=3,byrow=T) )
xmin = -0.25
xmax = 0.25
for ( i in 1:3 ) {
for ( j in (i+1):4 ) {
plotPost( omegaSample[i,]-omegaSample[j,] , compVal=0.0 ,
xlab=bquote(omega[.(i)]-omega[.(j)]) ,
#breaks=unique( c( min(c(xmin,omegaSample[i,]-omegaSample[j,])),
# seq(xmin,xmax,len=20),
# max(c(xmax,omegaSample[i,]-omegaSample[j,])) )) ,
main="" , xlim=c(xmin,xmax) )
}
}
#saveGraph(file=paste0(fileNameRoot,"OmegaDiff"),type="eps")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.