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")
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")
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")