如何使用plot.mcmc将垂直线添加到后密度图?

时间:2012-06-07 05:03:16

标签: r jags

我经常在已知参数的模拟数据上运行JAGS模型。我喜欢mcmc个对象的默认绘图方法。但是,我想为每个建模参数添加abline(v=TRUE_VALUE)。这样可以快速检查后验是否合理。

当然我可以手动完成,或者可能重新发明轮子并编写我自己的功能。但我想知道是否有一种基于现有plot方法的优雅方式。

这是一个有效的例子:

require(rjags)
require(coda)

# simulatee data
set.seed(4444)
N <- 100 
Mu <- 100
Sigma <- 15
y <- rnorm(n=N, mean=Mu, sd=Sigma)
jagsdata <- list(y=y)

jags.script <- "
model {
    for (i in 1:length(y)) {
        y[i]  ~ dnorm(mu, tau)
    }
    mu  ~ dnorm(0, 0.001)    
    sigma ~ dunif(0, 1000)
    tau <- 1/sigma^2
}"


mod1 <- jags.model(textConnection(jags.script), data=jagsdata, n.chains=4, 
                   n.adapt=1000)
update(mod1, 200) # burn in
mod1.samples <- coda.samples(model=mod1,
                             variable.names=c('mu', 'sigma'),
                             n.iter=1000)                  
plot(mod1.samples)

enter image description here

我只想为mu发送abline(v=100),为sigma运行abline(v=15)。当然在许多其他例子中,我会有5,10,20或更多感兴趣的参数。因此,我感兴趣的是能够为命名参数提供真值的向量。

我看过getAnywhere(plot.mcmc)。修改那是一个好方法吗?

1 个答案:

答案 0 :(得分:7)

好。所以我修改了plot.mcmc看起来像这样:

my.plot.mcmc <- function (x, trace = TRUE, density = TRUE, smooth = FALSE, bwf, 
    auto.layout = TRUE, ask = FALSE, parameters, ...) 
{
    oldpar <- NULL
    on.exit(par(oldpar))
    if (auto.layout) {
        mfrow <- coda:::set.mfrow(Nchains = nchain(x), Nparms = nvar(x), 
            nplots = trace + density)
        oldpar <- par(mfrow = mfrow)
    }
    for (i in 1:nvar(x)) {
        y <- mcmc(as.matrix(x)[, i, drop = FALSE], start(x), 
            end(x), thin(x))
        if (trace) 
            traceplot(y, smooth = smooth, ...)
        if (density) {
            if (missing(bwf)) {
                densplot(y, ...); abline(v=parameters[i])
            } else densplot(y, bwf = bwf, ...)
        }
        if (i == 1) 
            oldpar <- c(oldpar, par(ask = ask))
    }
}

然后运行命令

my.plot.mcmc(mod1.samples, parameters=c(Mu, Sigma))

产生这个

enter image description here

请注意,parameters必须是与JAGS排序变量的排序顺序相同的值向量,对于向量,这些变量似乎按字母顺序排列,然后是数字。

经验教训

  • 简单地写一个新的plot.mcmc在默认情况下不起作用,大概是因为命名空间。所以我刚刚创建了一个新功能
  • 我不得不将set.mfrow更改为coda:::set.mfrow,大概也是因为名称空间。
  • 我改变了对ask=FALSE的要求,因为RStudio允许浏览数字。

我很高兴听到有关更好地覆盖或改编现有S3方法的任何建议。