Simple models (linear and discretized age) and attitudes as a function of age. See Chapter 12 in Regression and Other Stories.


Load packages

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

Load data

data <- read.csv(root("Gay/data","naes04.csv"))
age <- seq(18,91)
response <- as.character(data[,"gayFavorStateMarriage"])
n_age <- length(age)
yes <- rep(NA, n_age)
no <- rep(NA, n_age)
for (i in 1:n_age){
  if (i == n_age)
    ok <- data[,"age"] >= age[i]
  else
    ok <- data[,"age"] == age[i]
  yes[i] <- sum(ok & response=="Yes", na.rm=TRUE)
  no[i] <- sum(ok & response=="No", na.rm=TRUE)
}

support <- yes/(yes + no)
age_cutpoints <- c(0, seq(29, 79, 10), 100)
age_discrete <- cut(age, age_cutpoints)
gay_total <- data.frame(support, age, age_discrete)

Fit linear regression model

fit_linear <- stan_glm(support ~ age, data=gay_total, refresh=0)
print(fit_linear)
stan_glm
 family:       gaussian [identity]
 formula:      support ~ age
 observations: 74
 predictors:   2
------
            Median MAD_SD
(Intercept) 0.6    0.0   
age         0.0    0.0   

Auxiliary parameter(s):
      Median MAD_SD
sigma 0.0    0.0   

------
* For help interpreting the printed output see ?print.stanreg
* For info on the priors used see ?prior_summary.stanreg

Fit discretized age model

fit_binned <- stan_glm(support ~ factor(age_discrete), data=gay_total, refresh=0)
print(fit_binned)
stan_glm
 family:       gaussian [identity]
 formula:      support ~ factor(age_discrete)
 observations: 74
 predictors:   7
------
                             Median MAD_SD
(Intercept)                   0.5    0.0  
factor(age_discrete)(29,39]  -0.1    0.0  
factor(age_discrete)(39,49]  -0.1    0.0  
factor(age_discrete)(49,59]  -0.1    0.0  
factor(age_discrete)(59,69]  -0.2    0.0  
factor(age_discrete)(69,79]  -0.3    0.0  
factor(age_discrete)(79,100] -0.3    0.0  

Auxiliary parameter(s):
      Median MAD_SD
sigma 0.0    0.0   

------
* For help interpreting the printed output see ?print.stanreg
* For info on the priors used see ?prior_summary.stanreg

Plot linear regression model

par(mar=c(3,3,01,0), mgp=c(1.7, .5, 0), tck=-.02)
plot(age, support, xlim=c(min(age)-1, max(age)+1), ylim=c(0, 0.65), xaxs="i", yaxs="i", xlab="Age", ylab="Support for same-sex marriage", xaxt="n", yaxt="n", bty="l", main="Linear regression", cex.main=1, type="n")
points(age, support, pch=20, col="gray40")
axis(1, seq(20, 80, 20))
axis(2, seq(0, 0.60, 0.20), paste(seq(0, 60, 20), "%", sep=""))
abline(coef(fit_linear)[1], coef(fit_linear)[2], lwd=2)

Plot discretized age model

par(mar=c(3,3,1,0), mgp=c(1.7, .5, 0), tck=-.02)
plot(age, support, xlim=c(min(age)-1, max(age)+1), ylim=c(0, 0.65), xaxs="i", yaxs="i", xlab="Age", ylab="Support for same-sex marriage", xaxt="n", yaxt="n", bty="l", main="Discretized age predictors", cex.main=1, type="n")
points(age, support, pch=20, col="gray40")
axis(1, seq(20, 80, 20))
axis(2, seq(0, 0.60, 0.20), paste(seq(0, 60, 20), "%", sep=""))
for (k in 1:(length(age_cutpoints) - 1)){
  lines(age_cutpoints[k:(k+1)], rep(coef(fit_binned)[1] + ifelse (k==1, 0, coef(fit_binned)[k]), 2), lwd=2)
}

LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBhbmQgT3RoZXIgU3RvcmllczogR2F5IgphdXRob3I6ICJBbmRyZXcgR2VsbWFuLCBBa2kgVmVodGFyaSIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQpTaW1wbGUgbW9kZWxzIChsaW5lYXIgYW5kIGRpc2NyZXRpemVkIGFnZSkgYW5kIGF0dGl0dWRlcyBhcyBhCmZ1bmN0aW9uIG9mIGFnZS4gU2VlIENoYXB0ZXIgMTIgaW4gUmVncmVzc2lvbiBhbmQgT3RoZXIgU3Rvcmllcy4KCi0tLS0tLS0tLS0tLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2U9RkFMU0UsIGVycm9yPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjb21tZW50PU5BKQojIHN3aXRjaCB0aGlzIHRvIFRSVUUgdG8gc2F2ZSBmaWd1cmVzIGluIHNlcGFyYXRlIGZpbGVzCnNhdmVmaWdzIDwtIEZBTFNFCmBgYAoKIyMjIyBMb2FkIHBhY2thZ2VzCgpgYGB7ciB9CmxpYnJhcnkoInJwcm9qcm9vdCIpCnJvb3Q8LWhhc19maWxlKCIuUk9TLUV4YW1wbGVzLXJvb3QiKSRtYWtlX2ZpeF9maWxlKCkKbGlicmFyeSgicnN0YW5hcm0iKQpgYGAKCiMjIyMgTG9hZCBkYXRhCgpgYGB7ciB9CmRhdGEgPC0gcmVhZC5jc3Yocm9vdCgiR2F5L2RhdGEiLCJuYWVzMDQuY3N2IikpCmFnZSA8LSBzZXEoMTgsOTEpCnJlc3BvbnNlIDwtIGFzLmNoYXJhY3RlcihkYXRhWywiZ2F5RmF2b3JTdGF0ZU1hcnJpYWdlIl0pCm5fYWdlIDwtIGxlbmd0aChhZ2UpCnllcyA8LSByZXAoTkEsIG5fYWdlKQpubyA8LSByZXAoTkEsIG5fYWdlKQpmb3IgKGkgaW4gMTpuX2FnZSl7CiAgaWYgKGkgPT0gbl9hZ2UpCiAgICBvayA8LSBkYXRhWywiYWdlIl0gPj0gYWdlW2ldCiAgZWxzZQogICAgb2sgPC0gZGF0YVssImFnZSJdID09IGFnZVtpXQogIHllc1tpXSA8LSBzdW0ob2sgJiByZXNwb25zZT09IlllcyIsIG5hLnJtPVRSVUUpCiAgbm9baV0gPC0gc3VtKG9rICYgcmVzcG9uc2U9PSJObyIsIG5hLnJtPVRSVUUpCn0KCnN1cHBvcnQgPC0geWVzLyh5ZXMgKyBubykKYWdlX2N1dHBvaW50cyA8LSBjKDAsIHNlcSgyOSwgNzksIDEwKSwgMTAwKQphZ2VfZGlzY3JldGUgPC0gY3V0KGFnZSwgYWdlX2N1dHBvaW50cykKZ2F5X3RvdGFsIDwtIGRhdGEuZnJhbWUoc3VwcG9ydCwgYWdlLCBhZ2VfZGlzY3JldGUpCmBgYAoKIyMjIyBGaXQgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwKCmBgYHtyIH0KZml0X2xpbmVhciA8LSBzdGFuX2dsbShzdXBwb3J0IH4gYWdlLCBkYXRhPWdheV90b3RhbCwgcmVmcmVzaD0wKQpwcmludChmaXRfbGluZWFyKQpgYGAKCiMjIyMgRml0IGRpc2NyZXRpemVkIGFnZSBtb2RlbAoKYGBge3IgfQpmaXRfYmlubmVkIDwtIHN0YW5fZ2xtKHN1cHBvcnQgfiBmYWN0b3IoYWdlX2Rpc2NyZXRlKSwgZGF0YT1nYXlfdG90YWwsIHJlZnJlc2g9MCkKcHJpbnQoZml0X2Jpbm5lZCkKYGBgCgojIyMjIFBsb3QgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIkdheS9maWdzIiwiZ2F5X3NpbXBsZV8xYS5wZGYiKSwgaGVpZ2h0PTMuNSwgd2lkdGg9NSkKYGBgCmBgYHtyIH0KcGFyKG1hcj1jKDMsMywwMSwwKSwgbWdwPWMoMS43LCAuNSwgMCksIHRjaz0tLjAyKQpwbG90KGFnZSwgc3VwcG9ydCwgeGxpbT1jKG1pbihhZ2UpLTEsIG1heChhZ2UpKzEpLCB5bGltPWMoMCwgMC42NSksIHhheHM9ImkiLCB5YXhzPSJpIiwgeGxhYj0iQWdlIiwgeWxhYj0iU3VwcG9ydCBmb3Igc2FtZS1zZXggbWFycmlhZ2UiLCB4YXh0PSJuIiwgeWF4dD0ibiIsIGJ0eT0ibCIsIG1haW49IkxpbmVhciByZWdyZXNzaW9uIiwgY2V4Lm1haW49MSwgdHlwZT0ibiIpCnBvaW50cyhhZ2UsIHN1cHBvcnQsIHBjaD0yMCwgY29sPSJncmF5NDAiKQpheGlzKDEsIHNlcSgyMCwgODAsIDIwKSkKYXhpcygyLCBzZXEoMCwgMC42MCwgMC4yMCksIHBhc3RlKHNlcSgwLCA2MCwgMjApLCAiJSIsIHNlcD0iIikpCmFibGluZShjb2VmKGZpdF9saW5lYXIpWzFdLCBjb2VmKGZpdF9saW5lYXIpWzJdLCBsd2Q9MikKYGBgCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgZGV2Lm9mZigpCmBgYAoKIyMjIyBQbG90IGRpc2NyZXRpemVkIGFnZSBtb2RlbAoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBwZGYocm9vdCgiR2F5L2ZpZ3MiLCJnYXlfc2ltcGxlXzFiLnBkZiIpLCBoZWlnaHQ9My41LCB3aWR0aD01KQpgYGAKYGBge3IgfQpwYXIobWFyPWMoMywzLDEsMCksIG1ncD1jKDEuNywgLjUsIDApLCB0Y2s9LS4wMikKcGxvdChhZ2UsIHN1cHBvcnQsIHhsaW09YyhtaW4oYWdlKS0xLCBtYXgoYWdlKSsxKSwgeWxpbT1jKDAsIDAuNjUpLCB4YXhzPSJpIiwgeWF4cz0iaSIsIHhsYWI9IkFnZSIsIHlsYWI9IlN1cHBvcnQgZm9yIHNhbWUtc2V4IG1hcnJpYWdlIiwgeGF4dD0ibiIsIHlheHQ9Im4iLCBidHk9ImwiLCBtYWluPSJEaXNjcmV0aXplZCBhZ2UgcHJlZGljdG9ycyIsIGNleC5tYWluPTEsIHR5cGU9Im4iKQpwb2ludHMoYWdlLCBzdXBwb3J0LCBwY2g9MjAsIGNvbD0iZ3JheTQwIikKYXhpcygxLCBzZXEoMjAsIDgwLCAyMCkpCmF4aXMoMiwgc2VxKDAsIDAuNjAsIDAuMjApLCBwYXN0ZShzZXEoMCwgNjAsIDIwKSwgIiUiLCBzZXA9IiIpKQpmb3IgKGsgaW4gMToobGVuZ3RoKGFnZV9jdXRwb2ludHMpIC0gMSkpewogIGxpbmVzKGFnZV9jdXRwb2ludHNbazooaysxKV0sIHJlcChjb2VmKGZpdF9iaW5uZWQpWzFdICsgaWZlbHNlIChrPT0xLCAwLCBjb2VmKGZpdF9iaW5uZWQpW2tdKSwgMiksIGx3ZD0yKQp9CmBgYApgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQppZiAoc2F2ZWZpZ3MpIGRldi5vZmYoKQpgYGAKCg==