Posterior predictive checking of Normal model for Newcomb's speed of light data. See Chapter 11 in Regression and Other Stories.
Load packages
library("rprojroot")
root<-has_file(".ROS-Examples-root")$make_fix_file()
library("rstanarm")
library("ggplot2")
library("bayesplot")
theme_set(bayesplot::theme_default(base_family = "sans"))
Load Data
Simon Newcomb's measurements of the speed of light, from Stigler (1977). The data are recorded as deviations from \(24,\!800\) nanoseconds.
newcomb <- read.table(root("Newcomb/data","newcomb.txt"), header = TRUE)
head(newcomb)
y
1 28
2 26
3 33
4 24
5 34
6 -44
Histogram of the data
hist(newcomb$y, main=NULL, ylab="", xlab="", yaxt="n", breaks=30)
Histogram of the data with bayesplot
mcmc_hist(newcomb, pars="y") + xlab("")
Fit a regression model with just the intercept term
The option refresh = 0
supresses the default Stan sampling progress output. This is useful for small data with fast computation. For more complex models and bigger data, it can be useful to see the progress.
fit <- stan_glm(y ~ 1, data=newcomb, refresh=0)
Simulate from the predictive distribution
sims <- as.matrix(fit)
n_sims <- nrow(sims)
n <- length(newcomb$y)
y_rep <- array(NA, c(n_sims, n))
for (s in 1:n_sims)
y_rep[s,] <- rnorm(n, sims[s,1], sims[s,2])
Plot histogram of 20 replicates
par(mfrow=c(4,5), mar=rep(2,4))
for (s in sample(n_sims, 20)) {
hist(y_rep[s,], main=NULL, ylab="", xlab="", yaxt="n") }
Simulate using built-in function
y_rep <- posterior_predict(fit)
Plot data and 19 replications using built-in function
ppc_hist(newcomb$y, y_rep[1:19, ], binwidth = 8)
Plot kernel density estimate of data and 100 replications using built-in function
ppc_dens_overlay(newcomb$y, y_rep[1:100, ]) + scale_y_continuous(breaks=NULL)
Plot test statistic for data and replicates
test <- function (y) {
min(y) }
test_rep <- apply(y_rep, 1, test)
hist(test_rep, xlim=c(-50,20), breaks=20, yaxt="n",
xlab="", ylab="", main=NULL)
lines(rep(test(newcomb$y),2), c(0,n_sims), lwd=3)
Plot test statistic for data and replicates using built-in function
ppc_stat(newcomb$y, y_rep, stat = "min", binwidth = 2)
LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBhbmQgT3RoZXIgU3RvcmllczogTmV3Y29tYiIKYXV0aG9yOiAiQW5kcmV3IEdlbG1hbiwgSmVubmlmZXIgSGlsbCwgQWtpIFZlaHRhcmkiCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSlgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiByZWFkYWJsZQogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KUG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2tpbmcgb2YgTm9ybWFsIG1vZGVsIGZvciBOZXdjb21iJ3Mgc3BlZWQKb2YgbGlnaHQgZGF0YS4gU2VlIENoYXB0ZXIgMTEgaW4gUmVncmVzc2lvbiBhbmQgT3RoZXIgU3Rvcmllcy4KCi0tLS0tLS0tLS0tLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjb21tZW50PU5BKQojIHN3aXRjaCB0aGlzIHRvIFRSVUUgdG8gc2F2ZSBmaWd1cmVzIGluIHNlcGFyYXRlIGZpbGVzCnNhdmVmaWdzIDwtIEZBTFNFCmBgYAoKIyMjIyBMb2FkIHBhY2thZ2VzCgpgYGB7ciB9CmxpYnJhcnkoInJwcm9qcm9vdCIpCnJvb3Q8LWhhc19maWxlKCIuUk9TLUV4YW1wbGVzLXJvb3QiKSRtYWtlX2ZpeF9maWxlKCkKbGlicmFyeSgicnN0YW5hcm0iKQpsaWJyYXJ5KCJnZ3Bsb3QyIikKbGlicmFyeSgiYmF5ZXNwbG90IikKdGhlbWVfc2V0KGJheWVzcGxvdDo6dGhlbWVfZGVmYXVsdChiYXNlX2ZhbWlseSA9ICJzYW5zIikpCmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIGdyYXlzY2FsZSBmaWd1cmVzIGZvciB0aGUgYm9vawpjb2xvcl9zY2hlbWVfc2V0KHNjaGVtZSA9ICJncmF5IikKYGBgCgojIyMjIExvYWQgRGF0YQoKU2ltb24gTmV3Y29tYidzIG1lYXN1cmVtZW50cyBvZiB0aGUgc3BlZWQgb2YgbGlnaHQsIGZyb20gU3RpZ2xlcgooMTk3NykuICBUaGUgZGF0YSBhcmUgcmVjb3JkZWQgYXMgZGV2aWF0aW9ucyBmcm9tICQyNCxcITgwMCQKbmFub3NlY29uZHMuCgpgYGB7ciB9Cm5ld2NvbWIgPC0gcmVhZC50YWJsZShyb290KCJOZXdjb21iL2RhdGEiLCJuZXdjb21iLnR4dCIpLCBoZWFkZXIgPSBUUlVFKQpoZWFkKG5ld2NvbWIpCmBgYAoKIyMjIyBIaXN0b2dyYW0gb2YgdGhlIGRhdGEKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIk5ld2NvbWIvZmlncyIsIm5ld2NvbWJfaGlzdC5wZGYiKSwgaGVpZ2h0PTQsIHdpZHRoPTUpCmBgYApgYGB7ciB9Cmhpc3QobmV3Y29tYiR5LCBtYWluPU5VTEwsIHlsYWI9IiIsIHhsYWI9IiIsIHlheHQ9Im4iLCBicmVha3M9MzApCmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQppZiAoc2F2ZWZpZ3MpIGRldi5vZmYoKQpgYGAKCiMjIyMgSGlzdG9ncmFtIG9mIHRoZSBkYXRhIHdpdGggYmF5ZXNwbG90CgpgYGB7ciB9Cm1jbWNfaGlzdChuZXdjb21iLCBwYXJzPSJ5IikgKyB4bGFiKCIiKQpgYGAKCiMjIyMgRml0IGEgcmVncmVzc2lvbiBtb2RlbCB3aXRoIGp1c3QgdGhlIGludGVyY2VwdCB0ZXJtCgpUaGUgb3B0aW9uIGByZWZyZXNoID0gMGAgc3VwcmVzc2VzIHRoZSBkZWZhdWx0IFN0YW4gc2FtcGxpbmcKcHJvZ3Jlc3Mgb3V0cHV0LiBUaGlzIGlzIHVzZWZ1bCBmb3Igc21hbGwgZGF0YSB3aXRoIGZhc3QKY29tcHV0YXRpb24uIEZvciBtb3JlIGNvbXBsZXggbW9kZWxzIGFuZCBiaWdnZXIgZGF0YSwgaXQgY2FuIGJlCnVzZWZ1bCB0byBzZWUgdGhlIHByb2dyZXNzLgoKYGBge3IgfQpmaXQgPC0gc3Rhbl9nbG0oeSB+IDEsIGRhdGE9bmV3Y29tYiwgcmVmcmVzaD0wKQpgYGAKCiMjIyMgU2ltdWxhdGUgZnJvbSB0aGUgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24KCmBgYHtyIH0Kc2ltcyA8LSBhcy5tYXRyaXgoZml0KQpuX3NpbXMgPC0gbnJvdyhzaW1zKQpuIDwtIGxlbmd0aChuZXdjb21iJHkpCnlfcmVwIDwtIGFycmF5KE5BLCBjKG5fc2ltcywgbikpCmZvciAocyBpbiAxOm5fc2ltcykKICAgIHlfcmVwW3MsXSA8LSBybm9ybShuLCBzaW1zW3MsMV0sIHNpbXNbcywyXSkKYGBgCgojIyMjIFBsb3QgaGlzdG9ncmFtIG9mIDIwIHJlcGxpY2F0ZXMKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIk5ld2NvbWIvZmlncyIsIm5ld2NvbWJfcmVwX2hpc3QucGRmIiksIGhlaWdodD00LCB3aWR0aD04KQpgYGAKYGBge3IgfQpwYXIobWZyb3c9Yyg0LDUpLCBtYXI9cmVwKDIsNCkpCmZvciAocyBpbiBzYW1wbGUobl9zaW1zLCAyMCkpIHsKICBoaXN0KHlfcmVwW3MsXSwgbWFpbj1OVUxMLCB5bGFiPSIiLCB4bGFiPSIiLCB5YXh0PSJuIikgfQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBkZXYub2ZmKCkKYGBgCgojIyMjIFNpbXVsYXRlIHVzaW5nIGJ1aWx0LWluIGZ1bmN0aW9uCgpgYGB7ciB9CnlfcmVwIDwtIHBvc3Rlcmlvcl9wcmVkaWN0KGZpdCkKYGBgCgojIyMjIFBsb3QgZGF0YSBhbmQgMTkgcmVwbGljYXRpb25zIHVzaW5nIGJ1aWx0LWluIGZ1bmN0aW9uCgpgYGB7ciB9CnBwY19oaXN0KG5ld2NvbWIkeSwgeV9yZXBbMToxOSwgXSwgYmlud2lkdGggPSA4KQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBnZ3NhdmUocm9vdCgiTmV3Y29tYi9maWdzIiwibmV3Y29tYl9wcGNfaGlzdC5wZGYiKSwgd2lkdGggPSA5LCBoZWlnaHQgPSA0KQpgYGAKCiMjIyMgUGxvdCBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBvZiBkYXRhIGFuZCAxMDAgcmVwbGljYXRpb25zIHVzaW5nIGJ1aWx0LWluIGZ1bmN0aW9uCgpgYGB7ciB9CnBwY19kZW5zX292ZXJsYXkobmV3Y29tYiR5LCB5X3JlcFsxOjEwMCwgXSkgKyBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPU5VTEwpCmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQppZiAoc2F2ZWZpZ3MpIGdnc2F2ZShyb290KCJOZXdjb21iL2ZpZ3MiLCJuZXdjb21iX3BwY19kZW5zX292ZXJsYXkucGRmIiksIHdpZHRoID0gNiwgaGVpZ2h0ID0gMi41KQpgYGAKCiMjIyMgUGxvdCB0ZXN0IHN0YXRpc3RpYyBmb3IgZGF0YSBhbmQgcmVwbGljYXRlcwoKYGBge3IgfQp0ZXN0IDwtIGZ1bmN0aW9uICh5KSB7CiAgbWluKHkpIH0KdGVzdF9yZXAgPC0gYXBwbHkoeV9yZXAsIDEsIHRlc3QpCmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQppZiAoc2F2ZWZpZ3MpIHBkZihyb290KCJOZXdjb21iL2ZpZ3MiLCJuZXdjb21iX3Rlc3RfaGlzdC5wZGYiKSwgaGVpZ2h0PTQsIHdpZHRoPTUpCmBgYApgYGB7ciB9Cmhpc3QodGVzdF9yZXAsIHhsaW09YygtNTAsMjApLCBicmVha3M9MjAsIHlheHQ9Im4iLAogICAgIHhsYWI9IiIsIHlsYWI9IiIsIG1haW49TlVMTCkKbGluZXMocmVwKHRlc3QobmV3Y29tYiR5KSwyKSwgYygwLG5fc2ltcyksIGx3ZD0zKQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBkZXYub2ZmKCkKYGBgCgojIyMjIFBsb3QgdGVzdCBzdGF0aXN0aWMgZm9yIGRhdGEgYW5kIHJlcGxpY2F0ZXMgdXNpbmcgYnVpbHQtaW4gZnVuY3Rpb24KCmBgYHtyIH0KcHBjX3N0YXQobmV3Y29tYiR5LCB5X3JlcCwgc3RhdCA9ICJtaW4iLCBiaW53aWR0aCA9IDIpCmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQppZiAoc2F2ZWZpZ3MpIGdnc2F2ZShyb290KCJOZXdjb21iL2ZpZ3MiLCJuZXdjb21iX3BwY19zdGF0LnBkZiIpLCB3aWR0aCA9IDYsIGhlaWdodCA9IDQpCmBgYAoK