Hierarchical model for SAT-example data (BDA3, p. 120)
ggplot2, grid, and gridExtra are used for plotting, tidyr for manipulating data frames
library(ggplot2)
theme_set(theme_minimal())
library(gridExtra)
library(tidyr)
library(latex2exp)
library(rprojroot)
root<-has_file(".BDA_R_demos_root")$make_fix_file()
Data
y <- c(28,8,-3,7,-1,1,18,12)
s <- c(15,10,16,11,9,11,10,18)
Plot data, use normpdf to plot both the y_j and sigma_j
x <- seq(-40, 60, length.out = 500)
df_sep <- mapply(function(y, s, x) dnorm(x, y, s), y, s, MoreArgs = list(x = x)) %>%
as.data.frame() %>%
setNames(LETTERS[1:8]) %>%
cbind(x) %>%
pivot_longer(cols = !x, names_to = "school", values_to = "p")
labs1 <- c('Other Schools', 'School A')
plot_sep <- ggplot(data = df_sep) +
geom_line(aes(x = x, y = p, color = (school=='A'), group = school)) +
labs(x = 'Treatment effect', y = '', title = 'Separate model', color = '') +
scale_y_continuous(breaks = NULL) +
scale_color_manual(values = c('blue','red'), labels = labs1) +
theme(legend.background = element_blank(), legend.position = c(0.8,0.9))
plot_sep
A pooled model
df_pool <- data.frame(x = x, p = dnorm(x, sum(y/s^2)/sum(1/s^2), sqrt(1/sum(1/s^2))))
Create plot for the pooled model
plot_pool <- ggplot(data = df_pool) +
geom_line(aes(x = x, y = p, color = '1')) +
labs(x = 'Treatment effect', y = '', title = 'Pooled model', color = '') +
scale_y_continuous(breaks = NULL) +
scale_color_manual(values = 'red', labels = 'All schools') +
theme(legend.background = element_blank(), legend.position = c(0.7,0.9))
Load the pre-computed results for the hierarchical model Replace this with your own code in the related exercise
load(root("demos_ch5","demo5_2.RData"))
Create plot for the hierarchical model
df_hier <- as.data.frame(t(pxm)) %>%
setNames(LETTERS[1:8]) %>%
cbind(x) %>%
pivot_longer(cols = !x, names_to = "school", values_to = "p")
plot_hier <- ggplot(data = df_hier) +
geom_line(aes(x = x, y = p, color = (school=='A'), group = school)) +
labs(x = 'Treatment effect', y = '', title = 'Hierarchical model', color = '') +
scale_y_continuous(breaks = NULL) +
scale_color_manual(values = c('blue','red'), labels = labs1) +
theme(legend.background = element_blank(), legend.position = c(0.8,0.9))
Plot separate, pooled, and hierarchical model
grid.arrange(plot_sep, plot_pool, plot_hier)
Various marginal and conditional posterior summaries
df_margpost = data.frame(x = t(tt), p = t(tp))
title1 <- TeX('Marginal posterior $p(\\tau | y)$')
plot_margpost <-
ggplot(data = df_margpost) +
geom_line(aes(x = x, y = p), color='forestgreen') +
labs(x = expression(tau), y = TeX('$p(\\tau | y)$'), title = title1) +
scale_y_continuous(breaks = 0) +
xlim(c(0, 35))
df_condmeans <- as.data.frame(t(tm)) %>%
setNames(LETTERS[1:8]) %>%
cbind(x = t(tt)) %>%
pivot_longer(cols = !x, names_to = "school", values_to = "p")
yl <- c(-5, 40)
title2 <- TeX('Conditional means E\\[$\\theta_j | \\tau , y $\\]')
plot_condmeans <- ggplot(data = df_condmeans) +
geom_line(aes(x = x, y = p, color = (school=='A'), group = school)) +
coord_cartesian(ylim = yl, xlim = c(0, 35)) +
labs(x = expression(tau), y = TeX('E\\[$\\theta_j | \\tau , y $\\]'), title = title2, color = '') +
scale_color_manual(values = c('blue','red'), labels = labs1) +
theme(legend.background = element_blank(), legend.position = c(0.8,0.9))
df_condsds <- as.data.frame(t(tsd)) %>%
setNames(LETTERS[1:8]) %>%
cbind(x = t(tt)) %>%
pivot_longer(cols = !x, names_to = "school", values_to = "p")
yl <- c(0, 25)
title3 <- TeX('Conditional standard deviations sd\\[$\\theta_j | \\tau , y $\\]')
plot_condsds <- ggplot(data = df_condsds) +
geom_line(aes(x = x, y = p, color = (school=='A'), group = school)) +
coord_cartesian(ylim = yl, xlim = c(0,35)) +
labs(x = expression(tau), y = TeX('sd\\[$\\theta_j | \\tau , y $\\]'), title = title3, color = '') +
scale_color_manual(values = c('blue','red'), labels = labs1) +
theme(legend.background = element_blank(), legend.position = c(0.8,0.9))
Plot the posterior summaries
grid.arrange(plot_margpost, plot_condmeans, plot_condsds)
## Warning: Removed 125 row(s) containing missing values (geom_path).
LS0tCnRpdGxlOiAiQmF5ZXNpYW4gZGF0YSBhbmFseXNpcyBkZW1vIDUuMiIKYXV0aG9yOiAiQWtpIFZlaHRhcmksIE1hcmt1cyBQYWFzaW5pZW1pIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCkpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogcmVhZGFibGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCiMjIEhpZXJhcmNoaWNhbCBtb2RlbCBmb3IgU0FULWV4YW1wbGUgZGF0YSAoQkRBMywgcC4gMTIwKQoKZ2dwbG90MiwgZ3JpZCwgYW5kIGdyaWRFeHRyYSBhcmUgdXNlZCBmb3IgcGxvdHRpbmcsIHRpZHlyIGZvcgptYW5pcHVsYXRpbmcgZGF0YSBmcmFtZXMKCmBgYHtyIHNldHVwLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShnZ3Bsb3QyKQp0aGVtZV9zZXQodGhlbWVfbWluaW1hbCgpKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeSh0aWR5cikKbGlicmFyeShsYXRleDJleHApCmxpYnJhcnkocnByb2pyb290KQpyb290PC1oYXNfZmlsZSgiLkJEQV9SX2RlbW9zX3Jvb3QiKSRtYWtlX2ZpeF9maWxlKCkKYGBgCgpEYXRhIAoKYGBge3IgfQp5IDwtIGMoMjgsOCwtMyw3LC0xLDEsMTgsMTIpCnMgPC0gYygxNSwxMCwxNiwxMSw5LDExLDEwLDE4KQpgYGAKClBsb3QgZGF0YSwgdXNlIG5vcm1wZGYgdG8gcGxvdCBib3RoIHRoZSB5X2ogYW5kIHNpZ21hX2oKCmBgYHtyIH0KeCA8LSBzZXEoLTQwLCA2MCwgbGVuZ3RoLm91dCA9IDUwMCkKZGZfc2VwIDwtIG1hcHBseShmdW5jdGlvbih5LCBzLCB4KSBkbm9ybSh4LCB5LCBzKSwgeSwgcywgTW9yZUFyZ3MgPSBsaXN0KHggPSB4KSkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHNldE5hbWVzKExFVFRFUlNbMTo4XSkgJT4lCiAgY2JpbmQoeCkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAheCwgbmFtZXNfdG8gPSAic2Nob29sIiwgdmFsdWVzX3RvID0gInAiKQpsYWJzMSA8LSBjKCdPdGhlciBTY2hvb2xzJywgJ1NjaG9vbCBBJykKcGxvdF9zZXAgPC0gZ2dwbG90KGRhdGEgPSBkZl9zZXApICsKICBnZW9tX2xpbmUoYWVzKHggPSB4LCB5ID0gcCwgY29sb3IgPSAoc2Nob29sPT0nQScpLCBncm91cCA9IHNjaG9vbCkpICsKICBsYWJzKHggPSAnVHJlYXRtZW50IGVmZmVjdCcsIHkgPSAnJywgdGl0bGUgPSAnU2VwYXJhdGUgbW9kZWwnLCBjb2xvciA9ICcnKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygnYmx1ZScsJ3JlZCcpLCBsYWJlbHMgPSBsYWJzMSkgKwogIHRoZW1lKGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOCwwLjkpKQpgYGAKYGBge3IgZmlnLmhlaWdodD00fQpwbG90X3NlcApgYGAKCkEgcG9vbGVkIG1vZGVsCgpgYGB7ciB9CmRmX3Bvb2wgPC0gZGF0YS5mcmFtZSh4ID0geCwgcCA9IGRub3JtKHgsIHN1bSh5L3NeMikvc3VtKDEvc14yKSwgc3FydCgxL3N1bSgxL3NeMikpKSkKYGBgCgpDcmVhdGUgcGxvdCBmb3IgdGhlIHBvb2xlZCBtb2RlbAoKYGBge3IgfQpwbG90X3Bvb2wgPC0gZ2dwbG90KGRhdGEgPSBkZl9wb29sKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHAsIGNvbG9yID0gJzEnKSkgKwogIGxhYnMoeCA9ICdUcmVhdG1lbnQgZWZmZWN0JywgeSA9ICcnLCB0aXRsZSA9ICdQb29sZWQgbW9kZWwnLCBjb2xvciA9ICcnKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gJ3JlZCcsIGxhYmVscyA9ICdBbGwgc2Nob29scycpICsKICB0aGVtZShsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjcsMC45KSkKYGBgCgpMb2FkIHRoZSBwcmUtY29tcHV0ZWQgcmVzdWx0cyBmb3IgdGhlIGhpZXJhcmNoaWNhbCBtb2RlbApSZXBsYWNlIHRoaXMgd2l0aCB5b3VyIG93biBjb2RlIGluIHRoZSByZWxhdGVkIGV4ZXJjaXNlCgpgYGB7ciB9CmxvYWQocm9vdCgiZGVtb3NfY2g1IiwiZGVtbzVfMi5SRGF0YSIpKQpgYGAKCkNyZWF0ZSBwbG90IGZvciB0aGUgaGllcmFyY2hpY2FsIG1vZGVsCgpgYGB7ciB9CmRmX2hpZXIgPC0gYXMuZGF0YS5mcmFtZSh0KHB4bSkpICU+JQogIHNldE5hbWVzKExFVFRFUlNbMTo4XSkgJT4lCiAgY2JpbmQoeCkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAheCwgbmFtZXNfdG8gPSAic2Nob29sIiwgdmFsdWVzX3RvID0gInAiKQpwbG90X2hpZXIgPC0gZ2dwbG90KGRhdGEgPSBkZl9oaWVyKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHAsIGNvbG9yID0gKHNjaG9vbD09J0EnKSwgZ3JvdXAgPSBzY2hvb2wpKSArCiAgbGFicyh4ID0gJ1RyZWF0bWVudCBlZmZlY3QnLCB5ID0gJycsIHRpdGxlID0gJ0hpZXJhcmNoaWNhbCBtb2RlbCcsIGNvbG9yID0gJycpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCdibHVlJywncmVkJyksIGxhYmVscyA9IGxhYnMxKSArCiAgdGhlbWUobGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC44LDAuOSkpCmBgYAoKUGxvdCBzZXBhcmF0ZSwgcG9vbGVkLCBhbmQgaGllcmFyY2hpY2FsIG1vZGVsCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmdyaWQuYXJyYW5nZShwbG90X3NlcCwgcGxvdF9wb29sLCBwbG90X2hpZXIpCmBgYAoKVmFyaW91cyBtYXJnaW5hbCBhbmQgY29uZGl0aW9uYWwgcG9zdGVyaW9yIHN1bW1hcmllcwoKYGBge3IgfQpkZl9tYXJncG9zdCA9IGRhdGEuZnJhbWUoeCA9IHQodHQpLCBwID0gdCh0cCkpCnRpdGxlMSA8LSBUZVgoJ01hcmdpbmFsIHBvc3RlcmlvciAkcChcXHRhdSB8IHkpJCcpCnBsb3RfbWFyZ3Bvc3QgPC0KICBnZ3Bsb3QoZGF0YSA9IGRmX21hcmdwb3N0KSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHApLCBjb2xvcj0nZm9yZXN0Z3JlZW4nKSArCiAgbGFicyh4ID0gZXhwcmVzc2lvbih0YXUpLCB5ID0gVGVYKCckcChcXHRhdSB8IHkpJCcpLCB0aXRsZSA9IHRpdGxlMSkgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IDApICsKICAgIHhsaW0oYygwLCAzNSkpCgoKZGZfY29uZG1lYW5zIDwtIGFzLmRhdGEuZnJhbWUodCh0bSkpICU+JQogIHNldE5hbWVzKExFVFRFUlNbMTo4XSkgJT4lCiAgY2JpbmQoeCA9IHQodHQpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9ICF4LCBuYW1lc190byA9ICJzY2hvb2wiLCB2YWx1ZXNfdG8gPSAicCIpCgp5bCA8LSBjKC01LCA0MCkKdGl0bGUyIDwtIFRlWCgnQ29uZGl0aW9uYWwgbWVhbnMgRVxcWyRcXHRoZXRhX2ogfCBcXHRhdSAsIHkgJFxcXScpCnBsb3RfY29uZG1lYW5zIDwtIGdncGxvdChkYXRhID0gZGZfY29uZG1lYW5zKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geCwgeSA9IHAsIGNvbG9yID0gKHNjaG9vbD09J0EnKSwgZ3JvdXAgPSBzY2hvb2wpKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSB5bCwgeGxpbSA9IGMoMCwgMzUpKSArCiAgbGFicyh4ID0gZXhwcmVzc2lvbih0YXUpLCB5ID0gVGVYKCdFXFxbJFxcdGhldGFfaiB8IFxcdGF1ICwgeSAkXFxdJyksIHRpdGxlID0gdGl0bGUyLCBjb2xvciA9ICcnKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ2JsdWUnLCdyZWQnKSwgbGFiZWxzID0gbGFiczEpICsKICB0aGVtZShsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjgsMC45KSkKCmRmX2NvbmRzZHMgPC0gYXMuZGF0YS5mcmFtZSh0KHRzZCkpICU+JQogIHNldE5hbWVzKExFVFRFUlNbMTo4XSkgJT4lCiAgY2JpbmQoeCA9IHQodHQpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9ICF4LCBuYW1lc190byA9ICJzY2hvb2wiLCB2YWx1ZXNfdG8gPSAicCIpCgp5bCA8LSBjKDAsIDI1KQp0aXRsZTMgPC0gVGVYKCdDb25kaXRpb25hbCBzdGFuZGFyZCBkZXZpYXRpb25zIHNkXFxbJFxcdGhldGFfaiB8IFxcdGF1ICwgeSAkXFxdJykKcGxvdF9jb25kc2RzIDwtIGdncGxvdChkYXRhID0gZGZfY29uZHNkcykgKwogIGdlb21fbGluZShhZXMoeCA9IHgsIHkgPSBwLCBjb2xvciA9IChzY2hvb2w9PSdBJyksIGdyb3VwID0gc2Nob29sKSkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0geWwsIHhsaW0gPSBjKDAsMzUpKSArCiAgbGFicyh4ID0gZXhwcmVzc2lvbih0YXUpLCB5ID0gVGVYKCdzZFxcWyRcXHRoZXRhX2ogfCBcXHRhdSAsIHkgJFxcXScpLCB0aXRsZSA9IHRpdGxlMywgY29sb3IgPSAnJykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCdibHVlJywncmVkJyksIGxhYmVscyA9IGxhYnMxKSArCiAgdGhlbWUobGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC44LDAuOSkpCmBgYAoKUGxvdCB0aGUgcG9zdGVyaW9yIHN1bW1hcmllcwoKYGBge3IgZmlnLmhlaWdodD04fQpncmlkLmFycmFuZ2UocGxvdF9tYXJncG9zdCwgcGxvdF9jb25kbWVhbnMsIHBsb3RfY29uZHNkcykKYGBgCgo=