Set various values needed, including names of files and FIPS codes for New Hampshire and South Carolina

nhdatafile <- "NHD2016.xlsx"
nhdatafilecsv <- "NHD2016.csv"
usshapefile <- "cb_2014_us_county_5m/cb_2014_us_county_5m.shp" #keep entire name
nhfipscode <- "33"
scdatafile <- "SCGOP2016.csv"
scfipscode <- "45"

Install neccasary packages

#install.packages("tmap")
#install.packages("tmaptools")
#install.packages("leaflet") 
#install.packages("scales") 
#install.packages("leaflet.extras")
#install.packages("rio")
#install.packages("htmlwidgets") 
#install.packages("sf") 
#install.packages("sp")

Set working directory

setwd("C:/Users/jakea/OneDrive/Desktop/MC 2022/DATA-110/GIS")

lLoad the tmap, tmaptools, and leaflet packages into your working session

library(tidyverse) 
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.0     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.1     ✔ tibble    3.1.8
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(tmap) 
## Warning: package 'tmap' was built under R version 4.2.3
library(tmaptools) 
## Warning: package 'tmaptools' was built under R version 4.2.3
library(leaflet) 
## Warning: package 'leaflet' was built under R version 4.2.3
library(sf) 
## Warning: package 'sf' was built under R version 4.2.3
## Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(leaflet.extras) 
## Warning: package 'leaflet.extras' was built under R version 4.2.3
library(dplyr) 
library(rio) 
## Warning: package 'rio' was built under R version 4.2.3
library(sp)
## Warning: package 'sp' was built under R version 4.2.3
library(scales) 
## Warning: package 'scales' was built under R version 4.2.3
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(raster) 
## Warning: package 'raster' was built under R version 4.2.3
## 
## Attaching package: 'raster'
## 
## The following object is masked from 'package:dplyr':
## 
##     select

Step 1: Read in the NH election results file

nhdata <- import("NHD2016.csv")

Eliminate columns for minor candidates and just use County, Clinton and Sanders columns

nhdata <- nhdata[,c("County", "Clinton", "Sanders")]

Step 2: Decide what data to map

nhdata$SandersMarginVotes <- nhdata$Sanders - nhdata$Clinton 
nhdata$SandersPct <- (nhdata$Sanders) / (nhdata$Sanders + nhdata$Clinton) 
# Will use formatting later to multiply by a hundred
nhdata$ClintonPct <- (nhdata$Clinton) / (nhdata$Sanders + nhdata$Clinton) 
nhdata$SandersMarginPctgPoints <- nhdata$SandersPct - nhdata$ClintonPct

Step 3: Get geographic data files and read in the shapefile for US states and counties

#install.packages("raster")
#install.packages("rgdal")
library(raster) 
library(rgdal) 
## Warning: package 'rgdal' was built under R version 4.2.3
## Please note that rgdal will be retired during 2023,
## plan transition to sf/stars/terra functions using GDAL and PROJ
## at your earliest convenience.
## See https://r-spatial.org/r/2022/04/12/evolution.html and https://github.com/r-spatial/evolution
## rgdal: version: 1.6-5, (SVN revision 1199)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 3.5.2, released 2022/09/02
## Path to GDAL shared files: C:/Users/jakea/AppData/Local/R/win-library/4.2/rgdal/gdal
## GDAL binary built with GEOS: TRUE 
## Loaded PROJ runtime: Rel. 8.2.1, January 1st, 2022, [PJ_VERSION: 821]
## Path to PROJ shared files: C:/Users/jakea/AppData/Local/R/win-library/4.2/rgdal/proj
## PROJ CDN enabled: FALSE
## Linking to sp version:1.6-0
## To mute warnings of possible GDAL/OSR exportToProj4() degradation,
## use options("rgdal_show_exportToProj4_warnings"="none") before loading sp or rgdal.
usgeo <- shapefile("cb_2014_us_county_5m/cb_2014_us_county_5m.shp") 
## Warning: [vect] Z coordinates ignored

Quick Plot (qtm stands for quick thematic map) of the shapefile and check its structure

tmap_options(check.and.fix = TRUE)
qtm(usgeo) 
## Warning: The shape usgeo is invalid. See sf::st_is_valid

view(usgeo)

Subset just the NH data from the US shapefile

nhfipscode <- "33" # Need to define NH varablie to the correct FIPS code which is "33" for NH
nhgeo <- usgeo[usgeo$STATEFP==nhfipscode,]

tmap test plot of the New Hampshire data

qtm(nhgeo)

View the structure of the object

str(nhgeo) 
## Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
##   ..@ data       :'data.frame':  10 obs. of  9 variables:
##   .. ..$ STATEFP : chr [1:10] "33" "33" "33" "33" ...
##   .. ..$ COUNTYFP: chr [1:10] "009" "011" "007" "001" ...
##   .. ..$ COUNTYNS: chr [1:10] "00873178" "00873179" "00873177" "00873174" ...
##   .. ..$ AFFGEOID: chr [1:10] "0500000US33009" "0500000US33011" "0500000US33007" "0500000US33001" ...
##   .. ..$ GEOID   : chr [1:10] "33009" "33011" "33007" "33001" ...
##   .. ..$ NAME    : chr [1:10] "Grafton" "Hillsborough" "Coos" "Belknap" ...
##   .. ..$ LSAD    : chr [1:10] "06" "06" "06" "06" ...
##   .. ..$ ALAND   : int [1:10] 130959956 -2025747080 353249502 1036582289 1799805954 1830366195 955401980 -1875570227 -1883508361 1391587566
##   .. ..$ AWATER  : int [1:10] 105375486 41604851 90773891 177039345 259517418 57990901 39157548 57788894 158933434 38070546
##   ..@ polygons   :List of 10
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.8 43.9
##   .. .. .. .. .. .. ..@ area   : num 0.508
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:327, 1:2] -72.3 -72.3 -72.3 -72.3 -72.3 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:327] "33809" "33810" "33811" "33812" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.8 43.9
##   .. .. .. ..@ ID       : chr "686"
##   .. .. .. ..@ area     : num 0.508
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.7 42.9
##   .. .. .. .. .. .. ..@ area   : num 0.255
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:45, 1:2] -72.1 -72 -72 -72 -72 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:45] "44340" "44341" "44342" "44343" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.7 42.9
##   .. .. .. ..@ ID       : chr "867"
##   .. .. .. ..@ area     : num 0.255
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.3 44.7
##   .. .. .. .. .. .. ..@ area   : num 0.539
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:511, 1:2] -71.8 -71.8 -71.8 -71.7 -71.7 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:511] "49011" "49012" "49013" "49014" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.3 44.7
##   .. .. .. ..@ ID       : chr "923"
##   .. .. .. ..@ area     : num 0.539
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.4 43.5
##   .. .. .. .. .. .. ..@ area   : num 0.136
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:33, 1:2] -71.7 -71.7 -71.7 -71.7 -71.7 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:33] "58419" "58420" "58421" "58422" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.4 43.5
##   .. .. .. ..@ ID       : chr "1101"
##   .. .. .. ..@ area     : num 0.136
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.1 43
##   .. .. .. .. .. .. ..@ area   : num 0.208
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:123, 1:2] -71.5 -71.4 -71.4 -71.4 -71.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:123] "70583" "70584" "70585" "70586" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.1 43
##   .. .. .. ..@ ID       : chr "1279"
##   .. .. .. ..@ area     : num 0.208
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -72.3 42.9
##   .. .. .. .. .. .. ..@ area   : num 0.208
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:161, 1:2] -72.6 -72.6 -72.6 -72.6 -72.6 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:161] "112007" "112008" "112009" "112010" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -72.3 42.9
##   .. .. .. ..@ ID       : chr "1878"
##   .. .. .. ..@ area     : num 0.208
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71 43.3
##   .. .. .. .. .. .. ..@ area   : num 0.11
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:177, 1:2] -71.2 -71.2 -71.2 -71.2 -71.1 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:177] "170105" "170106" "170107" "170108" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71 43.3
##   .. .. .. ..@ ID       : chr "2677"
##   .. .. .. ..@ area     : num 0.11
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.7 43.3
##   .. .. .. .. .. .. ..@ area   : num 0.274
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:49, 1:2] -72.1 -72.1 -72 -72.1 -72.1 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:49] "178463" "178464" "178465" "178466" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.7 43.3
##   .. .. .. ..@ ID       : chr "2774"
##   .. .. .. ..@ area     : num 0.274
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.2 43.9
##   .. .. .. .. .. .. ..@ area   : num 0.288
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:73, 1:2] -71.6 -71.4 -71.4 -71.3 -71.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:73] "199379" "199380" "199381" "199382" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.2 43.9
##   .. .. .. ..@ ID       : chr "3078"
##   .. .. .. ..@ area     : num 0.288
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -72.2 43.4
##   .. .. .. .. .. .. ..@ area   : num 0.159
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:118, 1:2] -72.5 -72.4 -72.4 -72.4 -72.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:118] "204356" "204357" "204358" "204359" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -72.2 43.4
##   .. .. .. ..@ ID       : chr "3168"
##   .. .. .. ..@ area     : num 0.159
##   ..@ plotOrder  : int [1:10] 3 1 9 8 2 6 5 10 4 7
##   ..@ bbox       : num [1:2, 1:2] -72.6 42.7 -70.7 45.3
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : chr [1:2] "x" "y"
##   .. .. ..$ : chr [1:2] "min" "max"
##   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
##   .. .. ..@ projargs: chr "+proj=longlat +datum=NAD83 +no_defs"
##   .. .. ..$ comment: chr "GEOGCRS[\"unknown\",\n    DATUM[\"North American Datum 1983\",\n        ELLIPSOID[\"GRS 1980\",6378137,298.2572"| __truncated__
##   ..$ comment: chr "FALSE"
str(nhdata$County) 
##  chr [1:10] "Belknap" "Carroll" "Cheshire" "Coos" "Grafton" "Hillsborough" ...

They’re not. Change the county names to plain characters in nhgeo

nhgeo$NAME <- as.character(nhgeo$NAME)

Order each data set by county name

nhgeo <- nhgeo[order(nhgeo$NAME),] 
nhdata <- nhdata[order(nhdata$County),] 

Are the two county columns identical now? They should be

identical(nhgeo$NAME,nhdata$County) 
## [1] TRUE

Step 4: Merge geo data with results data using the merge function

library(sf) # sf stands for simple features# 
nhmap <- merge(nhgeo, nhdata, by.x = "NAME", by.y = "County") 
# See the new data structure with
str(nhmap) 
## Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
##   ..@ data       :'data.frame':  10 obs. of  15 variables:
##   .. ..$ NAME                   : chr [1:10] "Belknap" "Carroll" "Cheshire" "Coos" ...
##   .. ..$ STATEFP                : chr [1:10] "33" "33" "33" "33" ...
##   .. ..$ COUNTYFP               : chr [1:10] "001" "003" "005" "007" ...
##   .. ..$ COUNTYNS               : chr [1:10] "00873174" "00873175" "00873176" "00873177" ...
##   .. ..$ AFFGEOID               : chr [1:10] "0500000US33001" "0500000US33003" "0500000US33005" "0500000US33007" ...
##   .. ..$ GEOID                  : chr [1:10] "33001" "33003" "33005" "33007" ...
##   .. ..$ LSAD                   : chr [1:10] "06" "06" "06" "06" ...
##   .. ..$ ALAND                  : int [1:10] 1036582289 -1883508361 1830366195 353249502 130959956 -2025747080 -1875570227 1799805954 955401980 1391587566
##   .. ..$ AWATER                 : int [1:10] 177039345 158933434 57990901 90773891 105375486 41604851 57788894 259517418 39157548 38070546
##   .. ..$ Clinton                : int [1:10] 3495 3230 5132 2013 6918 28147 12250 22829 8813 2497
##   .. ..$ Sanders                : int [1:10] 6005 5638 12441 3639 14245 39245 18107 31065 15881 5915
##   .. ..$ SandersMarginVotes     : int [1:10] 2510 2408 7309 1626 7327 11098 5857 8236 7068 3418
##   .. ..$ SandersPct             : num [1:10] 0.632 0.636 0.708 0.644 0.673 ...
##   .. ..$ ClintonPct             : num [1:10] 0.368 0.364 0.292 0.356 0.327 ...
##   .. ..$ SandersMarginPctgPoints: num [1:10] 0.264 0.272 0.416 0.288 0.346 ...
##   ..@ polygons   :List of 10
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.4 43.5
##   .. .. .. .. .. .. ..@ area   : num 0.136
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:33, 1:2] -71.7 -71.7 -71.7 -71.7 -71.7 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:33] "58419" "58420" "58421" "58422" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.4 43.5
##   .. .. .. ..@ ID       : chr "1101"
##   .. .. .. ..@ area     : num 0.136
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.2 43.9
##   .. .. .. .. .. .. ..@ area   : num 0.288
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:73, 1:2] -71.6 -71.4 -71.4 -71.3 -71.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:73] "199379" "199380" "199381" "199382" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.2 43.9
##   .. .. .. ..@ ID       : chr "3078"
##   .. .. .. ..@ area     : num 0.288
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -72.3 42.9
##   .. .. .. .. .. .. ..@ area   : num 0.208
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:161, 1:2] -72.6 -72.6 -72.6 -72.6 -72.6 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:161] "112007" "112008" "112009" "112010" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -72.3 42.9
##   .. .. .. ..@ ID       : chr "1878"
##   .. .. .. ..@ area     : num 0.208
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.3 44.7
##   .. .. .. .. .. .. ..@ area   : num 0.539
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:511, 1:2] -71.8 -71.8 -71.8 -71.7 -71.7 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:511] "49011" "49012" "49013" "49014" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.3 44.7
##   .. .. .. ..@ ID       : chr "923"
##   .. .. .. ..@ area     : num 0.539
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.8 43.9
##   .. .. .. .. .. .. ..@ area   : num 0.508
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:327, 1:2] -72.3 -72.3 -72.3 -72.3 -72.3 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:327] "33809" "33810" "33811" "33812" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.8 43.9
##   .. .. .. ..@ ID       : chr "686"
##   .. .. .. ..@ area     : num 0.508
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.7 42.9
##   .. .. .. .. .. .. ..@ area   : num 0.255
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:45, 1:2] -72.1 -72 -72 -72 -72 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:45] "44340" "44341" "44342" "44343" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.7 42.9
##   .. .. .. ..@ ID       : chr "867"
##   .. .. .. ..@ area     : num 0.255
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.7 43.3
##   .. .. .. .. .. .. ..@ area   : num 0.274
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:49, 1:2] -72.1 -72.1 -72 -72.1 -72.1 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:49] "178463" "178464" "178465" "178466" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.7 43.3
##   .. .. .. ..@ ID       : chr "2774"
##   .. .. .. ..@ area     : num 0.274
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71.1 43
##   .. .. .. .. .. .. ..@ area   : num 0.208
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:123, 1:2] -71.5 -71.4 -71.4 -71.4 -71.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:123] "70583" "70584" "70585" "70586" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71.1 43
##   .. .. .. ..@ ID       : chr "1279"
##   .. .. .. ..@ area     : num 0.208
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -71 43.3
##   .. .. .. .. .. .. ..@ area   : num 0.11
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:177, 1:2] -71.2 -71.2 -71.2 -71.2 -71.1 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:177] "170105" "170106" "170107" "170108" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -71 43.3
##   .. .. .. ..@ ID       : chr "2677"
##   .. .. .. ..@ area     : num 0.11
##   .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
##   .. .. .. ..@ Polygons :List of 1
##   .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
##   .. .. .. .. .. .. ..@ labpt  : num [1:2] -72.2 43.4
##   .. .. .. .. .. .. ..@ area   : num 0.159
##   .. .. .. .. .. .. ..@ hole   : logi FALSE
##   .. .. .. .. .. .. ..@ ringDir: int 1
##   .. .. .. .. .. .. ..@ coords : num [1:118, 1:2] -72.5 -72.4 -72.4 -72.4 -72.4 ...
##   .. .. .. .. .. .. .. ..- attr(*, "dimnames")=List of 2
##   .. .. .. .. .. .. .. .. ..$ : chr [1:118] "204356" "204357" "204358" "204359" ...
##   .. .. .. .. .. .. .. .. ..$ : chr [1:2] "x" "y"
##   .. .. .. ..@ plotOrder: int 1
##   .. .. .. ..@ labpt    : num [1:2] -72.2 43.4
##   .. .. .. ..@ ID       : chr "3168"
##   .. .. .. ..@ area     : num 0.159
##   ..@ plotOrder  : int [1:10] 4 5 2 7 6 3 8 10 1 9
##   ..@ bbox       : num [1:2, 1:2] -72.6 42.7 -70.7 45.3
##   .. ..- attr(*, "dimnames")=List of 2
##   .. .. ..$ : chr [1:2] "x" "y"
##   .. .. ..$ : chr [1:2] "min" "max"
##   ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
##   .. .. ..@ projargs: chr "+proj=longlat +datum=NAD83 +no_defs"
##   .. .. ..$ comment: chr "GEOGCRS[\"unknown\",\n    DATUM[\"North American Datum 1983\",\n        ELLIPSOID[\"GRS 1980\",6378137,298.2572"| __truncated__
##   ..$ comment: chr "FALSE"

Step 5: Create a static map with tmap’s qtm() function

qtm(nhmap, "SandersMarginVotes")
## Some legend labels were too wide. These labels have been resized to 0.62, 0.62, 0.62, 0.57, 0.53. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.

Some legend labels were too wide. These labels have been resized to 0.62, 0.62, 0.62,

qtm(nhmap, "SandersMarginPctgPoints")

For more control over look and feel, use the tm_shape() function

tm_shape(nhmap) +
 tm_fill("SandersMarginVotes", title="Sanders Margin, Total Votes", palette = "PRGn") +
 tm_borders(alpha=.5) +
 tm_text("NAME", size=0.8)
## Some legend labels were too wide. These labels have been resized to 0.62, 0.62, 0.62, 0.57, 0.53. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.

Same code as above, but store the static map in a variable, and change the theme to “classic” style

nhstaticmap <- tm_shape(nhmap) + 
tm_fill("SandersMarginVotes", title="Sanders Margin, Total Votes", palette = "viridis") +
#I like viridis
tm_borders(alpha=.5) + 
tm_text("NAME", size=0.8) + 
tm_style("classic") 

View the map

nhstaticmap 
## Some legend labels were too wide. These labels have been resized to 0.62, 0.62, 0.62, 0.57, 0.53. Increase legend.width (argument of tm_layout) to make the legend wider and therefore the labels larger.

Save the map to a jpg file with tmap’s tmap_save()

tmap_save(nhstaticmap, filename="nhdemprimary.jpg")
## Map saved to C:\Users\jakea\OneDrive\Desktop\MC 2022\DATA-110\GIS\nhdemprimary.jpg
## Resolution: 1501.336 by 2937.385 pixels
## Size: 5.004452 by 9.791282 inches (300 dpi)

Part 6: Code for a basic interactive map, this time for Clinton percentages in NH

Create a palette and a pop-up window

clintonPalette <- colorNumeric(palette = "Blues", domain=nhmap$ClintonPct)
nhpopup <- paste0("County: ", nhmap$NAME, "Sanders ", percent(nhmap$SandersPct), " - Clinton ", percent(nhmap$ClintonPct)) 

Step 7: Now generate the interactive map

# re-project
nhmap_projected <- sp::spTransform(nhmap, "+proj=longlat +datum=WGS84") 
leaflet(nhmap_projected) %>% 
 addProviderTiles("CartoDB.Positron") %>% 
 addPolygons(stroke=FALSE, 
 smoothFactor = 0.2, 
 fillOpacity = .8, 
 popup=nhpopup, 
 color= ~clintonPalette(nhmap$ClintonPct))

South Carolina data

scdata <- rio::import(scdatafile)

South Carolina shapefile and Quick plot of scgeo SC geospatial object

scgeo <- usgeo[usgeo@data$STATEFP=="45",] 
qtm(scgeo)

Add a column with percent of votes for each candidate. Candidates are in columns 2-7

candidates <- colnames(scdata[2:7]) 
for(i in 2:7){ 
 j = i + 7
 temp <- scdata[[i]] / scdata$Total 
 scdata[[j]] <- temp 
 colnames(scdata)[j] <- paste0(colnames(scdata)[i], "Pct") 
} 
winner <- colnames(scdata[2:7]) 

Get winner in each precinct

for(i in 1:nrow(scdata)){ 
 scdata$winner[i] <- names(which.max(scdata[i,2:7])) 
}

Import spreadsheet with percent of adult population holding at least a 4-yr college degree

sced <- rio::import("SCdegree.xlsx") 

Check if county names are in the same format in both files

str(scgeo$NAME) 
##  chr [1:46] "Edgefield" "Lee" "Horry" "Allendale" "Marion" "Dorchester" ...
## chr [1:46] "Edgefield" "Lee" "Horry" "Allendale" "Marion" "Dorchester" ... 
str(scdata$County) 
##  chr [1:46] "Abbeville" "Aiken" "Allendale" "Anderson" "Bamberg" "Barnwell" ...
## chr [1:46] "Abbeville" "Aiken" "Allendale" "Anderson" "Bamberg" "Barnwell" ... 
# Change the county names to plain characters in scgeo:
scgeo$NAME <- as.character(scgeo$NAME) 
# Order each data set by county name
scgeo <- scgeo[order(scgeo$NAME),] 
scdata <- scdata[order(scdata$County),] 
# Are the two county columns identical now? They should be:
identical(scgeo$NAME,scdata$County ) 
## [1] TRUE

Add the election results and rename county column

scmap <- merge(scgeo, scdata, by.x = "NAME", by.y = "County")

Instead of just coloring the winner, let’s color by strength of win with multiple layers

# Use same intensity for all - get minimum and maximum for the top 3 combined
minpct <- min(c(scdata$`Donald J TrumpPct`, scdata$`Marco RubioPct`, scdata$`Ted CruzPct`
)) 
maxpct <- max(c(scdata$`Donald J TrumpPct`, scdata$`Marco RubioPct`, scdata$`Ted CruzPct`
)) 

Create leaflet palettes for each layer of the map

trumpPalette <- colorNumeric(palette = "Purples", domain=c(minpct, maxpct)) 
rubioPalette <- colorNumeric(palette = "Reds", domain = c(minpct, maxpct)) 
cruzPalette <- colorNumeric(palette = "Oranges", domain = c(minpct, maxpct)) 
winnerPalette <- colorFactor(palette=c("#984ea3", "#e41a1c"), domain = scmap$winner) 
edPalette <- colorNumeric(palette = "Blues", domain=scmap$PctCollegeDegree) 

Create a pop-up

scpopup <- paste0("<b>County: ", scmap$NAME, "<br />Winner: ", scmap$winner, "<br />Trump: ", percent(scmap$`Donald J TrumpPct`), "<br />Rubio: ", percent(scmap$`Marco RubioPct`), "<br />Cruz: ", percent(scmap$`Ted CruzPct`), "<br /><br />Pct w college ed: 
", sced$PctCollegeDegree, "% vs state-wide avg of 25%") 

Add the projection we know from the NH map we’ll need for this data on a Leaflet map

scmap <- sp::spTransform(scmap, "+proj=longlat +datum=WGS84")

Basic interactive map showing winner in each county

leaflet(scmap) %>% 
 addProviderTiles("CartoDB.Positron") %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~winnerPalette(scmap$winner), 
 group="Winners" ) %>% 
 addLegend(position="bottomleft", colors=c("#984ea3", "#e41a1c"), labels=c("Trump", "Rubio")) 

Put top 3 candidates in their own layers and add education layer, store in scGOPmap variable

scGOPmap <- leaflet(scmap) %>% 
 addProviderTiles("CartoDB.Positron") %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~winnerPalette(scmap$winner), 
 group="Winners" ) %>% 
 addLegend(position="bottomleft", colors=c("#984ea3", "#e41a1c"), labels=c("Trump", "Rubio")) %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~trumpPalette(scmap$`Donald J TrumpPct`), 
 group="Trump") %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~rubioPalette(scmap$`Marco RubioPct`), 
 group="Rubio") %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~cruzPalette(scmap$`Ted CruzPct`), 
 group="Cruz") %>% 
 addPolygons(stroke=TRUE, 
 weight=1, 
 smoothFactor = 0.2, 
 fillOpacity = .75, 
 popup=scpopup, 
 color= ~edPalette(sced$PctCollegeDegree), #this data is in the sced table, not scmaps
 group="College degs") %>% 
 addLayersControl( 
 baseGroups=c("Winners", "Trump", "Rubio", "Cruz", "College degs"), 
 position = "bottomleft", 
 options = layersControlOptions(collapsed = FALSE)) 
# Now display the map
scGOPmap %>%
addSearchOSM() # add a search for extra

Save as a self-contained HTML file

htmlwidgets::saveWidget(scGOPmap, file="scGOPwidget.html")
# save as an HTML file with dependencies in another directory:
htmlwidgets::saveWidget(widget=scGOPmap, file="scGOPprimary_withdependencies.html", selfcontained=FALSE, libdir = "js")