This document is part of the replication folder for the article ‘Capturing Rationalization Bias and Differential Item Functioning: A Unified Bayesian Scaling Approach’ in Political Analysis. It provides an overview of functions that may be convenient for future use of the BAM2 and ISR models.
The most relevant functions are included in the file functions_general.R
. Assuming the replication folder is your working directory, the functions can be loaded as follows:
source("scripts/functions_general.R")
The function prep.data
turns the data into a list that can be fed to rstan
’s stan
or sampling
functions. The prep.data
function takes a vector of \(N\) centered self-placements, an \(N \times J\) matrix of centered stimuli-placements (where \(J\) is the number of stimuli), and a similar matrix of preferences. While Stan does not accept NAs, the function does, and you can use the option allow.miss
to set how many missing values to permit for an individual to still be included in the analysis. By default, an observation is counted as missing when either the preference or stimuli placement is missing. Adding the option req.only.Y = TRUE
will ignore missing values on preferences, and consider only stimuli placements, which may be suitable when fitting the BAM2 model. The prep.data
function can be used as follows:
load("data/data_example.R") # Loading a subset of Estonian data (from EES 2009).
dat <- prep.data(self, ppos, prefs, allow.miss = 1)
The functions inits.BAM
and inits.2
can be used to generate starting values. Given the similarities between the BAM2 and ISR models, inits.2
should be used for both, while the original BAM model would use inits.BAM
. Fitting the models, we can either separate compilation and sampling, using stan_model
and sampling
(as in the article), or use stan
to do both:
require("rstan")
fit.ISR <- stan(file = "models/m_ISR.stan", init = inits.2, data = dat, chains = 3, cores = 3, verbose = FALSE)
fit.BAM2 <- stan(file = "models/m_BAM2.stan", init = inits.2, data = dat, chains = 3, cores = 3, verbose = FALSE)
The function get.estimates
extracts estimates from a fitted model. Because the function rescales the original self-placements, it also requires the data as input. The function returns a list of estimates, including 95% credible intervals as well as posterior means and medians. It can be used as follows:
est.ISR <- get.estimates(fit.ISR, dat)
est.BAM2 <- get.estimates(fit.BAM2, dat)
To see the structure of the returned object for a given model, use e.g. str(est.ISR)
.
Below is a simple plot of posterior median estimates from both models. We see that the models disagree on whether the voters are flipping the scale in some instances where the ISR model detects high rationalization.
require(ggplot2)
d <- data.frame(est.ISR$vpos[, 2], est.BAM2$vpos[, 2], est.ISR$gamma.CI[, 2])
colnames(d) <- c("Voter estimate, ISR", "Voter estimate, BAM2", "Rationalization")
ggplot(d, aes(x = `Voter estimate, ISR`, y = `Voter estimate, BAM2`, color = Rationalization)) + geom_point(alpha = .7)