library(dplyr)
## 
## Attaching package: 'dplyr'
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library(magrittr)
## 
## Attaching package: 'magrittr'
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
library(cartographer)
library(USAboundaries)
library(ggmap)
## Loading required package: ggplot2
## 
## Attaching package: 'ggmap'
## 
## The following object is masked from 'package:magrittr':
## 
##     inset
library(mullenMisc)
library(knitr)
library(DT) 
load("data/nnv.rda")

Get just the Massachusetts gubernatorial elections, clean out the duplicate counts at the county and state levels, tidy data so we get all the town-like ennumeration in a single column:

ma <- nnv %>% 
  filter(state == "Massachusetts",
         office == "Governor") %>%
  filter(!is.na(city) |
         !is.na(town) |
         !is.na(district) |
         !is.na(populated.place)) %>% 
  gather(type_town, town, c(11, 13:20), na.rm = TRUE)

Geocoding is tricky. On the one hand, it’s reasonably safe to assume that towns haven’t moved (though they have broken into geographically smaller towns, and place names change). But on the other hand, all of the towns that are currently in Maine were in Massachusetts in 1820. So we will geocode with the county name. We will also have to take the county name and figure out what state it is in. We’ll assume that Franklin county is in Massachusetts, not Maine.

sp <- us_boundaries(as.Date("1850-01-01"), type = "county", state = c("Maine", "Massachusetts"))

counties <- data_frame(county = tolower(sp@data$name), 
                       state = as.character(sp@data$state)) %>%
  filter(!(county == "franklin" & state == "Maine"))

counties$county[counties$county == "kennebec"] <- "kennebeck"
towns_file <- "data/ma-towns.rda"
if(!file.exists(towns_file)) {
  towns <- ma %>%
    select(town, county) %>%
    distinct(town, county) %>%
    mutate(state = lookup(tolower(county), counties)) %>%
    mutate(location = paste(town, ", ", county, " County, ", state, 
                            sep = ""))
  
    coords <- geocode(towns$location)
    towns <- cbind(towns, coords)
  
    save(towns, file = towns_file)
  } else {
    load(towns_file)
  }

Let’s see if our geocoding is at all reasonable by plotting towns:

cartographer() %>%
  tile_layer() %>%
  points_layer(data = towns, x = "lon", y = "lat", label = "Towns")

Fix a few points.

towns[towns$town == "Union",]$lon <- -69.27417
towns[towns$town == "Union",]$lat <- 44.21139
towns[towns$town == "Wayne",]$lon <- -70.06616
towns[towns$town == "Wayne",]$lat <- 44.34868
towns[towns$town == "Number 8 and 9",]$lat <- NA
towns[towns$town == "Number 8 and 9",]$lon <- NA

Now we can do a merge to associate the town coordinates with the voting data.

ma <- ma %>%
  left_join(towns, by = c("town", "county"))

Let’s try making a map of the three leading candidates in the 1800 gubernatorial election.

ma %>%
  filter(date == "1800") %>%
  group_by(name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  ungroup() %>%
  arrange(desc(vote)) %>%
  top_n(3, vote) %>%
  kable()
name affiliation vote
Caleb Strong Federalist 19867
Elbridge Gerry Republican 17187
Moses Gill Federalist 2018
cs <- ma %>%
  filter(name == "Caleb Strong",
         date == "1800") %>%
  select(name, town, lon, lat, vote)
eg <- ma %>%
  filter(name == "Elbridge Gerry",
         date == "1800") %>%
  select(name, town, lon, lat, vote)
mg <- ma %>%
  filter(name == "Moses Gill",
         date == "1800") %>%
  select(name, town, lon, lat, vote)

ma1800 <- as.Date("1800-06-01") %>%
  us_boundaries(type = "county", states = "Massachusetts") %>%
  sp_to_geojson()

# Very important to use the same scale!
scale <- "d3.scale.sqrt().domain([0, 1500]).range([0, 20])"

cartographer(bbox = list(c(-73.52142, 44.45240), c(-68.94993, 41.24133))) %>%
  tile_layer() %>%
  geojson_layer(ma1800, fill = "rgba(255,255,255,0)", stroke = "orange",
                label = "MA Counties") %>%
  points_layer(data = cs, x = "lon", y = "lat", radius_field = "vote",
               color = "red", label = "Strong (Fed)", radius_func = scale) %>%
  points_layer(data = eg, x = "lon", y = "lat", radius_field = "vote",
               color = "blue", label = "Gerry (Rep)", radius_func = scale,
               visible = FALSE) %>%
  points_layer(data = mg, x = "lon", y = "lat", radius_field = "vote",
               color = "green", label = "Gill (Fed)", radius_func = scale,
               visible = FALSE)

And for the election of 1807, the first election where a Republican became governor of Massachusetts.

ma %>%
  filter(date == "1807") %>%
  group_by(name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  ungroup() %>%
  filter(vote >= 5) %>%
  arrange(desc(vote)) %>%
  kable()
name affiliation vote
James Sullivan Republican 42187
Caleb Strong Federalist 39826
others NA 250
Levi Lincoln NA 50
Dan Bisbee NA 10
js <- ma %>%
  filter(name == "James Sullivan",
         date == "1807") %>%
  select(name, town, lon, lat, vote)
cs <- ma %>%
  filter(name == "Caleb Strong",
         date == "1807") %>%
  select(name, town, lon, lat, vote)
ll <- ma %>%
  filter(name == "Levi Lincoln",
         date == "1807") %>%
  select(name, town, lon, lat, vote)

ma1800 <- as.Date("1807-06-01") %>%
  us_boundaries(type = "county", states = "Massachusetts") %>%
  sp_to_geojson()

# Very important to use the same scale!
scale <- "d3.scale.sqrt().domain([0, 3000]).range([0, 20])"

cartographer(bbox = list(c(-73.52142, 44.45240), c(-68.94993, 41.24133))) %>%
  tile_layer() %>%
  geojson_layer(ma1800, fill = "rgba(255,255,255,0)", stroke = "orange",
                label = "MA Counties") %>%
  points_layer(data = js, x = "lon", y = "lat", radius_field = "vote",
               color = "blue", label = "Sullivan (Rep)", radius_func = scale) %>%
  points_layer(data = cs, x = "lon", y = "lat", radius_field = "vote",
               color = "red", label = "Strong (Fed)", radius_func = scale,
               visible = FALSE) %>%
  points_layer(data = ll, x = "lon", y = "lat", radius_field = "vote",
               color = "green", label = "Lincoln (NA)", radius_func = scale,
               visible = FALSE)

Let’s figure out the changing political parties:

ma %>%
  group_by(date, affiliation) %>%
  summarize(party_vote = sum(vote)) %>% 
  filter(!is.na(affiliation), affiliation != "Democrat") %>%
  mutate(percentage = party_vote/sum(party_vote)) %>%
  ggplot(aes(x = as.numeric(date), y = percentage, color = affiliation)) +
  geom_point() + geom_line() +
  geom_hline(y = 0.5) +
  theme_minimal(16) +
  ggtitle("Vote (%) by Party in Elections for MA Governor, 1796-1824") +
  xlab("Date") + ylab("")

Top three candidates in each election:

ma %>%
  group_by(date, name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  group_by(date) %>%
  mutate(percentage = round(vote / sum(vote), 3)) %>%
  top_n(5, vote) %>%
  arrange(desc(vote)) %>%
  datatable(options = list(iDisplayLength = 5))

Winners:

winners <- ma %>%
  group_by(date, name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  group_by(date) %>%
  mutate(percentage = round(100 * vote / sum(vote, na.rm = TRUE), 1)) %>%
  top_n(1)
## Selecting by percentage
kable(winners)
date name affiliation vote percentage
1787 John Hancock NA 17026 69.2
1788 John Hancock NA 17821 80.5
1789 John Hancock NA 17264 80.8
1790 John Hancock NA 14263 86.2
1791 John Hancock NA 15996 93.9
1792 John Hancock NA 14637 86.6
1793 John Hancock NA 16482 90.0
1794 Samuel Adams NA 14434 61.5
1795 Samuel Adams NA 15976 90.2
1796 Samuel Adams Republican 15186 57.3
1797 Increase Sumner Federalist 14540 56.2
1798 Increase Sumner NA 18215 85.8
1799 Increase Sumner Federalist 24095 73.1
1800 Caleb Strong Federalist 19867 50.4
1801 Caleb Strong Federalist 25708 55.6
1802 Caleb Strong Federalist 30447 60.5
1803 Caleb Strong Federalist 30556 67.8
1804 Caleb Strong Federalist 30026 55.0
1805 Caleb Strong Federalist 35204 51.0
1806 Caleb Strong Federalist 37754 50.1
1807 James Sullivan Republican 42187 51.2
1808 James Sullivan Republican 43037 51.4
1809 Christopher Gore Federalist 48315 51.4
1810 Elbridge Gerry Republican 47747 51.3
1811 Elbridge Gerry Republican 43982 51.9
1812 Caleb Strong Federalist 53090 50.8
1813 Caleb Strong Federalist 57637 56.5
1814 Caleb Strong Federalist 57298 54.9
1815 Caleb Strong Federalist 51977 53.5
1816 John Brooks Federalist 50021 51.2
1817 John Brooks Federalist 46226 54.5
1818 John Brooks NA 39762 55.7
1819 John Brooks NA 43191 53.8
1820 John Brooks Federalist 30968 58.2
1821 John Brooks Federalist 28790 58.3
1822 John Brooks Federalist 28348 57.0
1823 William Eustis Republican 34603 52.5
1824 William Eustis Republican 39246 53.0
ma %>%
  group_by(date, name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  group_by(date) %>%
  mutate(percentage = round(vote / sum(vote, na.rm = TRUE), 3)) %>%
  filter(percentage > .1) %>%
  ggplot(aes(x = as.numeric(date), y = percentage, color = name)) +
  geom_line() + geom_point() +
  geom_hline(y = 0.5) +
  ggtitle("Contenders for MA Governor, 1787-1824") +
  theme_minimal(16) +
  ylim(0, 1) +
  xlab("Date") + ylab("Proportion of vote") +
  annotate("text", x = 1790, y = 0.96, label = "J. Hancock") +
  annotate("text", x = 1797, y = 0.92, label = "S. Adams") +
  annotate("text", x = 1790, y = 0.10, label = "J. Bowdoin") +
  annotate("text", x = 1800, y = 0.88, label = "I. Sumner") +
  annotate("text", x = 1805, y = 0.69, label = "C. Strong") +
  annotate("text", x = 1805, y = 0.30, label = "E. Gerry") +
  annotate("text", x = 1822, y = 0.40, label = "W. Eustis") +
  annotate("text", x = 1820, y = 0.60, label = "J. Brooks") +
  annotate("text", x = 1812, y = 0.44, label = "S. Dexter") +
  annotate("text", x = 1809, y = 0.54, label = "C. Gore") +
  annotate("text", x = 1798, y = 0.26, label = "J. Sullivan")

The 1823 election

ma %>%
  filter(date == "1823") %>%
  group_by(name, affiliation) %>%
  summarize(vote = sum(vote)) %>%
  ungroup() %>%
  filter(vote >= 5) %>%
  arrange(desc(vote)) %>%
  kable()
name affiliation vote
William Eustis Republican 34603
Harrison G. Otis Federalist 30503
others NA 739
John Philips NA 15
we <- ma %>%
  filter(name == "William Eustis",
         date == "1823") %>%
  select(name, town, lon, lat, vote)
ho <- ma %>%
  filter(name == "Harrison G. Otis",
         date == "1823") %>%
  select(name, town, lon, lat, vote)

ma1820 <- as.Date("1823-06-01") %>%
  us_boundaries(type = "county", states = "Massachusetts") %>%
  sp_to_geojson()

# Very important to use the same scale!
scale <- "d3.scale.sqrt().domain([0, 3000]).range([0, 20])"

cartographer(bbox = list(c(-73.52142, 43.5), c(-69.94993, 41.5))) %>%
  tile_layer() %>%
  geojson_layer(ma1820, fill = "rgba(255,255,255,0)", stroke = "orange",
                label = "MA Counties") %>%
  points_layer(data = we, x = "lon", y = "lat", radius_field = "vote",
               color = "blue", label = "Eustis (Rep)", radius_func = scale) %>%
  points_layer(data = ho, x = "lon", y = "lat", radius_field = "vote",
               color = "red", label = "Otis (Fed)", radius_func = scale,
               visible = FALSE)