Part 1: Map presidential elections results with the maps package

Alternative option: map whatever you want with the maps package.

1. Download the elections file from harvard database:

database (you can download directly into R, but that’s for another day. For now do it by hand and save the ifle on your disk)

2. Load the data, and clean it up:

You should aim to make a dataset at the state*year level, with information on the party who won in that state and that year.

  • Tip 1: you can define the color in that dataset already. Make sure it is defined as.character
  • Tip 2: the hardest thing here is to select the winning observations. There are hundreds of ways to do it in R, most of them un-intuitive. My favorite involves group_by then top_n, both from the dplyr package.
library(dplyr)
library(maps)

load("C:\\Users\\jy80530\\OneDrive - University of Georgia\\Course\\07 Spring 2020\\AAEC8610\\HW\\HW5\\1976-2016-president.RData")

# Figure out which state voted for which party, per year 
# i.e: MAX of votes
maxvotes<- x %>% 
  group_by(state, year) %>% 
  top_n(1, candidatevotes)

# Make a dataset with just year, state, state_fips, party, and candidate
# NOTE: I had to add dplyr:: here for an obscure reason 
# related to how r loads packages in memory. 
# Without it I was getting an error, but you might not... 
stateParty <- dplyr::select(maxvotes, year, state, state_fips, party, candidate)

# Clean party to just be D, R or other 
stateParty <- stateParty %>% mutate(color = party)

stateParty$color <- as.character(stateParty$color)
stateParty$color[stateParty$party == "democrat"] <- "blue"
stateParty$color[stateParty$party == "republican"] <- "red"
stateParty$color[stateParty$party != "democrat" & stateParty$party != "republican" ] <- "beige"

head(stateParty,5)
## # A tibble: 5 x 6
## # Groups:   state, year [5]
##    year state      state_fips party      candidate     color
##   <int> <I<chr>>        <int> <I<chr>>   <I<chr>>      <chr>
## 1  1976 Alabama             1 democrat   Carter, Jimmy blue 
## 2  1976 Alaska              2 republican Ford, Gerald  red  
## 3  1976 Arizona             4 republican Ford, Gerald  red  
## 4  1976 Arkansas            5 democrat   Carter, Jimmy blue 
## 5  1976 California          6 republican Ford, Gerald  red

3. Try to make a map just for one year:

If your data is in the right format, this takes very very command: - one command to subset data for just one a year - one command to select the observsations that match state.fips$fips - one command to map

  • Here’s an example of what you might obtain:
temp <- stateParty[stateParty$year==2000, c("state_fips","party", "color")]
temp <- temp[match(paste(state.fips$fips),paste(temp$state_fips)),]
map("state", col=temp$color, fill=T) 
title(main =  "Presidential election results by State in 2000", line =0.6, cex.main=0.8)

4. Now loop that code and map it over time:

  • If you are using base plots, you will need to define mfrow (with or without a layout grid)
  • If you are using ggplot, you can probably do it with facets, but I have not tried.
  • Here’s an example of what you might obtain:
# Note: you didn't actually need to use a layout here,
# because you have 11 maps so that fits well on a 3x4 grid
# with a legend on the side. 
# So mfrow=c(3,4) or c(4,3) was enough here. 
# However, I show you the layout command because it is more generic:
years=seq(min(stateParty$year),max(stateParty$year), by=4)
layout_mat <- matrix(1:length(years), nrow= 4, ncol=3, byrow = TRUE)
layout_mat[4,3] = 12
layout(layout_mat, widths=1, heights=1)
par(mfrow=c(4,3), mar=c(0,0,0,0), oma=c(0,0,0,0), mgp=c(0,0,0), bg="grey", xpd=NA)
for (i in years) {
  temp <- stateParty[stateParty$year==i, c("state_fips","color")]
  temp <- temp[match(paste(state.fips$fips),paste(temp$state_fips)),]
  map("state", col=temp$color, fill=T)
  box("outer", col="blue")  
  mtext(i,side=3,line=0.3, cex = 0.8)
}
plot.new() # This will put a plot in the 12th box. It is empty, but with title and legend.
title(main = "Presidential election results
      by State and year", line=0.5)
legend("center", legend = c("Republican", "Democrat", "Other")
       , fill=c("red","blue","beige"))

Part 2: Interactive Maps with Leaflet

1. Get familiar with the leaflet package

  • Start with something like this:
library(leaflet)

myMap <- leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap)
myMap
  • Play with the options given to you under providers$. for instance, check out OpenTopoMap, OpenMapSurfer, Esri.NatGeoWorldMap and as many others as you may want.

  • Use the pipe operator %>% to pass a setView command and see what happens. Try, for instance, setView(lat=33.947474, lng=-83.373671, zoom = 12).

  • Change the coordinates and zoom parameters at will.

2. Map Athens

myMap <- leaflet() %>% 
  addProviderTiles(providers$OpenTopoMap) %>%
  setView(lat=33.947474, lng=-83.373671, zoom = 12)
myMap

3. Add your own shapefiles

There are several files, but I suggest using the one called 210415_rrc_outline_block_al2.zip

Unzip the file and load the .shp into R like this:

library(raster)
library(rgdal)
sp <- shapefile("210413_RRC_Outline_Block_AL2.shp")
# Projection is necessary for R to place the coordinates correctly
campShapeFile <- spTransform(sp, CRS("+proj=longlat +datum=WGS84 +no_defs"))
  • Zoom your map onto South-Eastern Bangladesh (setView(92.14871, 21.18780, zoom = 12))
  • Add the shapefile to your map with:
myMap <- leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>%
  setView(92.14871, 21.18780, zoom = 12) %>%
  addPolygons(data=campShapeFile, fill=TRUE, stroke=T, weight=1,
        highlight = highlightOptions(fillOpacity = 0.7),
        label = campShapeFile$Block_No)
myMap

4. Add tiles from the web

  • Start a new leaflet map and zoom onto the USA.

  • See what happens when you add these tiles (with %>% of course):

myMap <- leaflet() %>% 
  setView(-96, 37.8, 4) %>%
  addProviderTiles(providers$OpenStreetMap) %>%
  addWMSTiles(
    "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
    layers = "nexrad-n0r-900913",
    options = WMSTileOptions(format = "image/png", transparent = TRUE),
    attribution = "Weather data © 2012 IEM Nexrad"
  )
myMap

Note: You just overlayed a raster image of current rainfall in the USA. It updates every few minutes. You can get lots of different raster files online from websites like this one.

5. For more excellent leaflet features