Individual Exercise Solution

Fit a one dimensional IRT model on Voeten, Strezhnev, and Bailey (2017)’s UN Voting Data, using countries as the unit of analysis. Treat abstentions as no votes, and absences as missing data (these data illustrate the limitations of canned code; a more accurate model could use a categorical logit instead of a binomial one because states often abstain for reasons separate from voting yea or nay, to say nothing of the fact that this is a static model for 70 years of data…). Report your results for the estimated ideal points, along with measures of uncertainty, in table and graphical form.

library(plyr)
library(countrycode)
library(pscl)
library(ggplot2)
library(plotly)

# read in UN voting data
UN <- read.delim('UNVotesPublished.tab', sep = '\t', quote = "")

# subset just to voting data
UN <- UN[, c('ccode', 'vote')]

UN_votes <- ddply(UN, 'ccode', function(x) t(x$vote))

UN_votes$ccode <- countrycode(UN_votes$ccode, origin = 'cown', destination = 'country.name')

# create rollcall object; code abstain and no as nay, absent as missing
UN_rc <- rollcall(data = UN_votes[, -1], legis.names = UN_votes[, 1], yea = 1,
                  nay = c(2, 3), missing = c(8, NA))

# fit IRT model
UN_irt <- ideal(UN_rc, normalize = T)
# extract empirical 95% CI
UN_df <- data.frame(UN_irt$xbar, t(apply(adply(UN_irt$x, 1)[, -1], 2, quantile, c(.025, .975))))
names(UN_df) <- c('mean', '2.5%', '97.5%')
UN_df <- UN_df[order(UN_irt$xbar), ]

# add country variable for plotly
UN_df$country <- rownames(UN_df)

# present results in paged dataframe
UN_df
## create ordering variable to use for x(y) axis
UN_df$order <- seq(1, length(UN_df$mean))

# plot ideal points and uncertainty
UN_gg <- ggplot(UN_df, aes(y = mean, x = order, ymin = `2.5%`,
                           ymax = `97.5%`, label = country)) +
  geom_point(aes(), cex = .25) +
  geom_linerange(size = .15, col = 'grey') +
  coord_flip() +
  theme_bw() +
  theme(plot.background = element_blank(),
        panel.grid.minor = element_blank(),
        panel.grid.major = element_blank(),
        panel.border = element_blank(),
        axis.title.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.y = element_blank(),
        axis.title.x = element_blank())

# interactive plot; ggplotly needs colour, not color
ggplotly(UN_gg, tooltip = c('label', 'mean'))

Voeten, Erik, Anton Strezhnev, and Michael Bailey. 2017. “United Nations General Assembly Voting Data.”