The politicaldata Package for Analyzing Political Data in R

I’ve written a R package for acquiring and analyzing political data. It’s now easier to explore polling, election results, demographic data and more.

By G. Elliott Morris

On Feb. 06, 2019  in Rstats R for Political Data



I have two dreams when it comes to data in politics. The first is that I will never rewrite the same computer program twice. I am failing miserably. The second is that more people will adopt statistical analysis for political journalism. In this, the only proper conclusion is that we have indeed made progress. But there is much further to go. To these ends, I have written an R package for acquiring and analyzing political data ā€” including polls, election results, legislator information, and demographic data. You can install the politicaldata package from CRAN or via GitHub.

I plan to write more here about the package as development continues. As it is in currently in version one, however, Iā€™ll illustrate just a few examples of how to use it.

Install the package

# install the remotes package if it's not already
if (!requireNamespace("remotes", quietly = TRUE)) {
  install.packages("remotes")
}

# install dev version of politicaldata from github
remotes::install_github("elliottmorris/politicaldata")

# load politicaldata package
library(politicaldata)

Map the 2012 and 2016 US presidential elections

# wrangle presidential eleciton data
library(politicaldata)

pres <- politicaldata::pres_results

pres <- pres %>% 
  filter(year%in% c(2012,2016))

pres$state_name = tolower(state.name[match(pres$state,state.abb)]) # we need the full name of the state to join with the map

# get map data
library(maps)
library(sf)
pres_map <- maps::map("state", plot = FALSE, fill = TRUE) # acquirig the data frame

pres_map <- sf::st_as_sf(pres_map) # changing the lat-long format to a simple feature object

names(pres_map) <- c("geometry","state_name")

pres_map <- pres_map %>% filter(state_name != 'district of columbia')

# combine with election data
pres_map <- pres_map %>% 
  left_join(pres,by = 'state_name') # joining the map with the political data
# plot with ggplot2
library(ggplot2)
ggplot(pres_map,
             aes(fill=dem-rep>0),
             col='black') +
  geom_sf(aes(alpha=abs(dem-rep))) +
  coord_sf(crs = "+proj=aea +lat_1=25 +lat_2=50 +lon_0=-100",ndiscr = 0) + # change the projection from mercator (blegh)
  scale_fill_manual(values=c("TRUE"="blue","FALSE"="red")) +
  scale_alpha(range=c(0.1,1)) +
  facet_wrap(~year,ncol=1) +
  theme_void() +
  theme(legend.position='none')

Download the latest NOMINATE data from the VoteView project

# import the package
library(politicaldata)

# download the NOMINATE scores for the 116th House
house_ideo <- get_house_nominate(congress = 116)

# download the NOMINATE scores for the Senate in the 116th Congress
senate_ideo <- get_senate_nominate(congress = 116)

# take a look with dplyr::head()
library(dplyr)

head(house_ideo[1:5])
##   congress chamber icpsr state_icpsr district_code
## 1      116   House 20301          41             3
## 2      116   House 21102          41             7
## 3      116   House 21192          41             2
## 4      116   House 21193          41             5
## 5      116   House 21376          41             1
## 6      116   House 21500          41             6