Predictive uncertainty for congressional elections. See Chapter 2 in Regression and Other Stories.


Load packages

library("rprojroot")
root<-has_file(".ROS-Examples-root")$make_fix_file()

Load and pre-process data

congress <- vector("list", 49)
for (i in 1:49){
  year <- 1896 + 2*(i-1)
  file <- root("Congress/data",paste(year, ".asc", sep=""))
  data_year <- matrix(scan(file), byrow=TRUE, ncol=5)
  data_year <- cbind(rep(year, nrow(data_year)), data_year)
  congress[[i]] <- data_year
}
region_name <- c("Northeast", "Midwest", "South", "West")
par(mfrow=c(3,5), mar=c(0.1,3,0,0), mgp=c(1.7, .3, 0), tck=-.02, oma=c(1,0,2,0))
for (i in c(27, 37, 47)) {
  year <- 1896 + 2*(i-1)
  cong1 <- congress[[i]]
  cong2 <- congress[[i+1]]
  state_code <- cong1[,2]
  region<- floor(state_code/20) + 1
  inc <- cong1[,4]
  dvote1 <- cong1[,5]/(cong1[,5] + cong1[,6])
  dvote2 <- cong2[,5]/(cong2[,5] + cong2[,6])
  contested <- (abs(dvote1 - 0.5)) < 0.3 & (abs(dvote2 - 0.5) < 0.3)
  plot(c(0, 1), c(0, 1), type="n", xlab="", ylab="", xaxt="n", yaxt="n", bty="n")
  text(0.8, 0.5, paste(year,"\nto\n", year+2, sep=""), cex=1.1)
  for (j in 1:4){
    plot(c(.2, .8), c(-.4, .3), type="n", xlab= "" , ylab=if (j==1) "Vote swing" else "", xaxt="n", yaxt="n", bty="n", cex.lab=.9)
    if (i==47) {
      text(c(.25, .5, .75), rep(-.4, 3), c("25%", "50%", "75%"), cex=.8)
      abline(-.35, 0, lwd=.5, col="gray60")
      segments(c(.25, .5, .75), rep(-.35, 35), c(.25, .5, .75), rep(-.37, 3), lwd=.5)
      mtext("Dem. vote in election 1", side=1, line=.2, cex=.5)
    }
    axis(2, c(-0.25, 0, 0.25), c("-25%", "0", "25%"),  cex.axis=.8)
    abline(0, 0)
    if (i==27) mtext(region_name[j], side=3, line=1, cex=.75)
    ok <- contested & abs(inc)==1 & region==j
    points(dvote1[ok], dvote2[ok] - dvote1[ok], pch=20, cex=.3, col="gray60")
    ok <- contested & abs(inc)==0 & region==j
    points(dvote1[ok], dvote2[ok] - dvote1[ok], pch=20, cex=.5, col="black")
  }
}

LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBhbmQgT3RoZXIgU3RvcmllczogQ29uZ3Jlc3MiCmF1dGhvcjogIkFuZHJldyBHZWxtYW4sIEplbm5pZmVyIEhpbGwsIEFraSBWZWh0YXJpIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCkpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tClByZWRpY3RpdmUgdW5jZXJ0YWludHkgZm9yIGNvbmdyZXNzaW9uYWwgZWxlY3Rpb25zLiBTZWUgQ2hhcHRlciAyCmluIFJlZ3Jlc3Npb24gYW5kIE90aGVyIFN0b3JpZXMuCgotLS0tLS0tLS0tLS0tCgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRSwgY29tbWVudD1OQSkKIyBzd2l0Y2ggdGhpcyB0byBUUlVFIHRvIHNhdmUgZmlndXJlcyBpbiBzZXBhcmF0ZSBmaWxlcwpzYXZlZmlncyA8LSBGQUxTRQpgYGAKCiMjIyMgTG9hZCBwYWNrYWdlcwoKYGBge3IgfQpsaWJyYXJ5KCJycHJvanJvb3QiKQpyb290PC1oYXNfZmlsZSgiLlJPUy1FeGFtcGxlcy1yb290IikkbWFrZV9maXhfZmlsZSgpCmBgYAoKIyMjIyBMb2FkIGFuZCBwcmUtcHJvY2VzcyBkYXRhCgpgYGB7ciB9CmNvbmdyZXNzIDwtIHZlY3RvcigibGlzdCIsIDQ5KQpmb3IgKGkgaW4gMTo0OSl7CiAgeWVhciA8LSAxODk2ICsgMiooaS0xKQogIGZpbGUgPC0gcm9vdCgiQ29uZ3Jlc3MvZGF0YSIscGFzdGUoeWVhciwgIi5hc2MiLCBzZXA9IiIpKQogIGRhdGFfeWVhciA8LSBtYXRyaXgoc2NhbihmaWxlKSwgYnlyb3c9VFJVRSwgbmNvbD01KQogIGRhdGFfeWVhciA8LSBjYmluZChyZXAoeWVhciwgbnJvdyhkYXRhX3llYXIpKSwgZGF0YV95ZWFyKQogIGNvbmdyZXNzW1tpXV0gPC0gZGF0YV95ZWFyCn0KcmVnaW9uX25hbWUgPC0gYygiTm9ydGhlYXN0IiwgIk1pZHdlc3QiLCAiU291dGgiLCAiV2VzdCIpCgpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBwZGYocm9vdCgiQ29uZ3Jlc3MvZmlncyIsImNvbmdyZXNzX3Bsb3RfZ3JpZC5wZGYiKSwgaGVpZ2h0PTMuOCwgd2lkdGg9NywgY29sb3Jtb2RlbD0iZ3JheSIpCmBgYApgYGB7ciB9CnBhcihtZnJvdz1jKDMsNSksIG1hcj1jKDAuMSwzLDAsMCksIG1ncD1jKDEuNywgLjMsIDApLCB0Y2s9LS4wMiwgb21hPWMoMSwwLDIsMCkpCmZvciAoaSBpbiBjKDI3LCAzNywgNDcpKSB7CiAgeWVhciA8LSAxODk2ICsgMiooaS0xKQogIGNvbmcxIDwtIGNvbmdyZXNzW1tpXV0KICBjb25nMiA8LSBjb25ncmVzc1tbaSsxXV0KICBzdGF0ZV9jb2RlIDwtIGNvbmcxWywyXQogIHJlZ2lvbjwtIGZsb29yKHN0YXRlX2NvZGUvMjApICsgMQogIGluYyA8LSBjb25nMVssNF0KICBkdm90ZTEgPC0gY29uZzFbLDVdLyhjb25nMVssNV0gKyBjb25nMVssNl0pCiAgZHZvdGUyIDwtIGNvbmcyWyw1XS8oY29uZzJbLDVdICsgY29uZzJbLDZdKQogIGNvbnRlc3RlZCA8LSAoYWJzKGR2b3RlMSAtIDAuNSkpIDwgMC4zICYgKGFicyhkdm90ZTIgLSAwLjUpIDwgMC4zKQogIHBsb3QoYygwLCAxKSwgYygwLCAxKSwgdHlwZT0ibiIsIHhsYWI9IiIsIHlsYWI9IiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgYnR5PSJuIikKICB0ZXh0KDAuOCwgMC41LCBwYXN0ZSh5ZWFyLCJcbnRvXG4iLCB5ZWFyKzIsIHNlcD0iIiksIGNleD0xLjEpCiAgZm9yIChqIGluIDE6NCl7CiAgICBwbG90KGMoLjIsIC44KSwgYygtLjQsIC4zKSwgdHlwZT0ibiIsIHhsYWI9ICIiICwgeWxhYj1pZiAoaj09MSkgIlZvdGUgc3dpbmciIGVsc2UgIiIsIHhheHQ9Im4iLCB5YXh0PSJuIiwgYnR5PSJuIiwgY2V4LmxhYj0uOSkKICAgIGlmIChpPT00NykgewogICAgICB0ZXh0KGMoLjI1LCAuNSwgLjc1KSwgcmVwKC0uNCwgMyksIGMoIjI1JSIsICI1MCUiLCAiNzUlIiksIGNleD0uOCkKICAgICAgYWJsaW5lKC0uMzUsIDAsIGx3ZD0uNSwgY29sPSJncmF5NjAiKQogICAgICBzZWdtZW50cyhjKC4yNSwgLjUsIC43NSksIHJlcCgtLjM1LCAzNSksIGMoLjI1LCAuNSwgLjc1KSwgcmVwKC0uMzcsIDMpLCBsd2Q9LjUpCiAgICAgIG10ZXh0KCJEZW0uIHZvdGUgaW4gZWxlY3Rpb24gMSIsIHNpZGU9MSwgbGluZT0uMiwgY2V4PS41KQogICAgfQogICAgYXhpcygyLCBjKC0wLjI1LCAwLCAwLjI1KSwgYygiLTI1JSIsICIwIiwgIjI1JSIpLCAgY2V4LmF4aXM9LjgpCiAgICBhYmxpbmUoMCwgMCkKICAgIGlmIChpPT0yNykgbXRleHQocmVnaW9uX25hbWVbal0sIHNpZGU9MywgbGluZT0xLCBjZXg9Ljc1KQogICAgb2sgPC0gY29udGVzdGVkICYgYWJzKGluYyk9PTEgJiByZWdpb249PWoKICAgIHBvaW50cyhkdm90ZTFbb2tdLCBkdm90ZTJbb2tdIC0gZHZvdGUxW29rXSwgcGNoPTIwLCBjZXg9LjMsIGNvbD0iZ3JheTYwIikKICAgIG9rIDwtIGNvbnRlc3RlZCAmIGFicyhpbmMpPT0wICYgcmVnaW9uPT1qCiAgICBwb2ludHMoZHZvdGUxW29rXSwgZHZvdGUyW29rXSAtIGR2b3RlMVtva10sIHBjaD0yMCwgY2V4PS41LCBjb2w9ImJsYWNrIikKICB9Cn0KYGBgCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgZGV2Lm9mZigpCmBgYAoK