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.
Examples
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
Learn more
Visit the package documentation for politicaldata to learn more. You can view the source code on GitHub