library("rgdal")
rgdal: version: 1.5-23, (SVN revision 1121)
Geospatial Data Abstraction Library extensions to R successfully loaded
Loaded GDAL runtime: GDAL 3.1.4, released 2020/10/20
Path to GDAL shared files: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/rgdal/gdal
GDAL binary built with GEOS: TRUE 
Loaded PROJ runtime: Rel. 6.3.1, February 10th, 2020, [PJ_VERSION: 631]
Path to PROJ shared files: /Library/Frameworks/R.framework/Versions/4.0/Resources/library/rgdal/proj
Linking to sp version:1.4-5
To mute warnings of possible GDAL/OSR exportToProj4() degradation,
use options("rgdal_show_exportToProj4_warnings"="none") before loading rgdal.
# 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"
nhfipscode <- "33"
scdatafile <- "SCGOP2016.csv"
scfipscode <- "45"
setwd("/Users/daniellefevre/Documents/DATA\ 110/NHDemPrimary/computerworldrmaptutorial/data")
The working directory was changed to /Users/daniellefevre/Documents/DATA 110/NHDemPrimary/computerworldrmaptutorial/data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
nhdata <- import(nhdatafilecsv)
nhdata <- nhdata[,c("County", "Clinton", "Sanders")]
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
setwd("/Users/daniellefevre/Documents/DATA\ 110/NHDemPrimary/computerworldrmaptutorial/data")
The working directory was changed to /Users/daniellefevre/Documents/DATA 110/NHDemPrimary/computerworldrmaptutorial/data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
usgeo <- shapefile("cb_2014_us_county_5m/cb_2014_us_county_5m.shp")
Z-dimension discarded

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   : chr [1:10] "4425927252" "2269220216" "4648216798" "1036582289" ...
  .. ..$ AWATER  : chr [1:10] "105375486" "41604851" "90773891" "177039345" ...
  ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.8 43.9
  .. .. .. ..@ ID       : chr "685"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.7 42.9
  .. .. .. ..@ ID       : chr "866"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.3 44.7
  .. .. .. ..@ ID       : chr "922"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.4 43.5
  .. .. .. ..@ ID       : chr "1100"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.1 43
  .. .. .. ..@ ID       : chr "1278"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -72.3 42.9
  .. .. .. ..@ ID       : chr "1877"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71 43.3
  .. .. .. ..@ ID       : chr "2676"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.7 43.3
  .. .. .. ..@ ID       : chr "2773"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.2 43.9
  .. .. .. ..@ ID       : chr "3077"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -72.2 43.4
  .. .. .. ..@ ID       : chr "3167"
  .. .. .. ..@ 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"
str(nhgeo$NAME)
 chr [1:10] "Grafton" "Hillsborough" "Coos" "Belknap" "Rockingham" "Cheshire" "Strafford" "Merrimack" "Carroll" "Sullivan"
str(nhdata$County)
 chr [1:10] "Belknap" "Carroll" "Cheshire" "Coos" "Grafton" "Hillsborough" "Merrimack" "Rockingham" "Strafford" "Sullivan"
nhgeo <- nhgeo[order(nhgeo$NAME),]
nhdata <- nhdata[order(nhdata$County),]
if (identical(nhgeo$NAME,nhdata$County)) {
nhmap <- merge(nhgeo, nhdata, by.x = "NAME", by.y = "County")  # Merge geo and vote datasets
} else {stop}
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                  : chr [1:10] "1036582289" "2411458935" "1830366195" "4648216798" ...
  .. ..$ AWATER                 : chr [1:10] "177039345" "158933434" "57990901" "90773891" ...
  .. ..$ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.4 43.5
  .. .. .. ..@ ID       : chr "1100"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.2 43.9
  .. .. .. ..@ ID       : chr "3077"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -72.3 42.9
  .. .. .. ..@ ID       : chr "1877"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.3 44.7
  .. .. .. ..@ ID       : chr "922"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.8 43.9
  .. .. .. ..@ ID       : chr "685"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.7 42.9
  .. .. .. ..@ ID       : chr "866"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.7 43.3
  .. .. .. ..@ ID       : chr "2773"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71.1 43
  .. .. .. ..@ ID       : chr "1278"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -71 43.3
  .. .. .. ..@ ID       : chr "2676"
  .. .. .. ..@ 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 ...
  .. .. .. ..@ plotOrder: int 1
  .. .. .. ..@ labpt    : num [1:2] -72.2 43.4
  .. .. .. ..@ ID       : chr "3167"
  .. .. .. ..@ 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"
qtm(nhmap, "SandersMarginVotes")

tm_shape(nhmap) +
  tm_fill("SandersMarginVotes", title="Sanders Margin, Total Votes", palette = "PRGn") +
  tm_borders(alpha=.5) +
  tm_text("NAME", size=0.8)
CRS object has comment, which is lost in output

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")
nhstaticmap
CRS object has comment, which is lost in output

tmap_save(nhstaticmap, filename="nhdemprimary.jpg") 
CRS object has comment, which is lost in output
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
nhpopup <- paste0("County: ", nhmap$NAME,
", Sanders ", percent(nhmap$SandersPct), " - Clinton ", percent(nhmap$ClintonPct))  # popup content
# add the appropriate projection, WGS84
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))
setwd("/Users/daniellefevre/Documents/DATA\ 110/NHDemPrimary/computerworldrmaptutorial/data")
The working directory was changed to /Users/daniellefevre/Documents/DATA 110/NHDemPrimary/computerworldrmaptutorial/data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
scdata <- rio::import(scdatafile)
scgeo <- usgeo[usgeo@data$STATEFP=="45",]
qtm(scgeo)

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])
for(i in 1:nrow(scdata)){
  scdata$winner[i] <- names(which.max(scdata[i,2:7]))
}
setwd("/Users/daniellefevre/Documents/DATA\ 110/NHDemPrimary/computerworldrmaptutorial/data")
The working directory was changed to /Users/daniellefevre/Documents/DATA 110/NHDemPrimary/computerworldrmaptutorial/data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
sced <- rio::import("SCdegree.xlsx")
str(scgeo$NAME)
 chr [1:46] "Edgefield" "Lee" "Horry" "Allendale" "Marion" "Dorchester" "Sumter" "Clarendon" "Bamberg" "Cherokee" "Williamsburg" "Aiken" ...
str(scdata$County)
 chr [1:46] "Abbeville" "Aiken" "Allendale" "Anderson" "Bamberg" "Barnwell" "Beaufort" "Berkeley" "Calhoun" "Charleston" "Cherokee" "Chester" ...
# 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),]
# check name and county columns are identical
if (identical(scgeo$NAME,scdata$County )) {
scmap <- merge(scgeo, scdata, by.x = "NAME", by.y = "County")
} else {stop}

# 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),]
str(scgeo$NAME)
 chr [1:46] "Abbeville" "Aiken" "Allendale" "Anderson" "Bamberg" "Barnwell" "Beaufort" "Berkeley" "Calhoun" "Charleston" "Cherokee" "Chester" ...
str(scdata$County)
 chr [1:46] "Abbeville" "Aiken" "Allendale" "Anderson" "Bamberg" "Barnwell" "Beaufort" "Berkeley" "Calhoun" "Charleston" "Cherokee" "Chester" ...
scmap <- merge(scgeo, scdata, by.x = "NAME", by.y = "County")
# 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`))
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)
scpopup <- paste0("<b>County: ", scmap$NAME, "<br />Winner: ", scmap$winner, "</b><br /><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%")
scmap <- sp::spTransform(scmap, "+proj=longlat +datum=WGS84")
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"))
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
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoInRtYXAiKQpsaWJyYXJ5KCJ0bWFwdG9vbHMiKQpsaWJyYXJ5KCJzZiIpCmxpYnJhcnkoImxlYWZsZXQiKQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQpsaWJyYXJ5KCJyaW8iKQpsaWJyYXJ5KCJzcCIpCmxpYnJhcnkoImxlYWZsZXQuZXh0cmFzIikKbGlicmFyeSgiZHBseXIiKQpsaWJyYXJ5KCJyYXN0ZXIiKQpsaWJyYXJ5KCJyZ2RhbCIpCmBgYAoKCmBgYHtyfQojIFNldCB2YXJpb3VzIHZhbHVlcyBuZWVkZWQsIGluY2x1ZGluZyBuYW1lcyBvZiBmaWxlcyBhbmQgRklQUyBjb2RlcyBmb3IgTmV3IEhhbXBzaGlyZSBhbmQgU291dGggQ2Fyb2xpbmEKbmhkYXRhZmlsZSA8LSAiTkhEMjAxNi54bHN4IgpuaGRhdGFmaWxlY3N2IDwtICJOSEQyMDE2LmNzdiIKdXNzaGFwZWZpbGUgPC0gImNiXzIwMTRfdXNfY291bnR5XzVtL2NiXzIwMTRfdXNfY291bnR5XzVtLnNocCIKbmhmaXBzY29kZSA8LSAiMzMiCnNjZGF0YWZpbGUgPC0gIlNDR09QMjAxNi5jc3YiCnNjZmlwc2NvZGUgPC0gIjQ1IgpgYGAKCmBgYHtyfQpzZXR3ZCgiL1VzZXJzL2RhbmllbGxlZmV2cmUvRG9jdW1lbnRzL0RBVEFcIDExMC9OSERlbVByaW1hcnkvY29tcHV0ZXJ3b3JsZHJtYXB0dXRvcmlhbC9kYXRhIikKbmhkYXRhIDwtIGltcG9ydChuaGRhdGFmaWxlY3N2KQpgYGAKCmBgYHtyfQpuaGRhdGEgPC0gbmhkYXRhWyxjKCJDb3VudHkiLCAiQ2xpbnRvbiIsICJTYW5kZXJzIildCmBgYAoKYGBge3J9Cm5oZGF0YSRTYW5kZXJzTWFyZ2luVm90ZXMgPC0gbmhkYXRhJFNhbmRlcnMgLSBuaGRhdGEkQ2xpbnRvbgpuaGRhdGEkU2FuZGVyc1BjdCA8LSAobmhkYXRhJFNhbmRlcnMpIC8gKG5oZGF0YSRTYW5kZXJzICsgbmhkYXRhJENsaW50b24pIAojIFdpbGwgdXNlIGZvcm1hdHRpbmcgbGF0ZXIgdG8gbXVsdGlwbHkgYnkgYSBodW5kcmVkCm5oZGF0YSRDbGludG9uUGN0IDwtIChuaGRhdGEkQ2xpbnRvbikgLyAobmhkYXRhJFNhbmRlcnMgKyBuaGRhdGEkQ2xpbnRvbikKbmhkYXRhJFNhbmRlcnNNYXJnaW5QY3RnUG9pbnRzIDwtIG5oZGF0YSRTYW5kZXJzUGN0IC0gbmhkYXRhJENsaW50b25QY3QKYGBgCgpgYGB7cn0Kc2V0d2QoIi9Vc2Vycy9kYW5pZWxsZWZldnJlL0RvY3VtZW50cy9EQVRBXCAxMTAvTkhEZW1QcmltYXJ5L2NvbXB1dGVyd29ybGRybWFwdHV0b3JpYWwvZGF0YSIpCnVzZ2VvIDwtIHNoYXBlZmlsZSgiY2JfMjAxNF91c19jb3VudHlfNW0vY2JfMjAxNF91c19jb3VudHlfNW0uc2hwIikKYGBgCgpgYGB7cn0KcXRtKHVzZ2VvKQpgYGAKCmBgYHtyfQpuaGdlbyA8LSB1c2dlb1t1c2dlbyRTVEFURUZQPT1uaGZpcHNjb2RlLF0KYGBgCgpgYGB7cn0KcXRtKG5oZ2VvKQpgYGAKCmBgYHtyfQpzdHIobmhnZW8pCmBgYAoKYGBge3J9CnN0cihuaGdlbyROQU1FKQpgYGAKCmBgYHtyfQpzdHIobmhkYXRhJENvdW50eSkKYGBgCgpgYGB7cn0KbmhnZW8kTkFNRSA8LSBhcy5jaGFyYWN0ZXIobmhnZW8kTkFNRSkKYGBgCgpgYGB7cn0KbmhnZW8gPC0gbmhnZW9bb3JkZXIobmhnZW8kTkFNRSksXQpuaGRhdGEgPC0gbmhkYXRhW29yZGVyKG5oZGF0YSRDb3VudHkpLF0KaWYgKGlkZW50aWNhbChuaGdlbyROQU1FLG5oZGF0YSRDb3VudHkpKSB7Cm5obWFwIDwtIG1lcmdlKG5oZ2VvLCBuaGRhdGEsIGJ5LnggPSAiTkFNRSIsIGJ5LnkgPSAiQ291bnR5IikgICMgTWVyZ2UgZ2VvIGFuZCB2b3RlIGRhdGFzZXRzCn0gZWxzZSB7c3RvcH0KYGBgCgpgYGB7cn0KbmhtYXAgPC0gbWVyZ2UobmhnZW8sIG5oZGF0YSwgYnkueCA9ICJOQU1FIiwgYnkueSA9ICJDb3VudHkiKQojIFNlZSB0aGUgbmV3IGRhdGEgc3RydWN0dXJlIHdpdGgKc3RyKG5obWFwKQpgYGAKCmBgYHtyfQpxdG0obmhtYXAsICJTYW5kZXJzTWFyZ2luVm90ZXMiKQpgYGAKCmBgYHtyfQp0bV9zaGFwZShuaG1hcCkgKwogIHRtX2ZpbGwoIlNhbmRlcnNNYXJnaW5Wb3RlcyIsIHRpdGxlPSJTYW5kZXJzIE1hcmdpbiwgVG90YWwgVm90ZXMiLCBwYWxldHRlID0gIlBSR24iKSArCiAgdG1fYm9yZGVycyhhbHBoYT0uNSkgKwogIHRtX3RleHQoIk5BTUUiLCBzaXplPTAuOCkKYGBgCgpgYGB7cn0KbmhzdGF0aWNtYXAgPC0gdG1fc2hhcGUobmhtYXApICsKdG1fZmlsbCgiU2FuZGVyc01hcmdpblZvdGVzIiwgdGl0bGU9IlNhbmRlcnMgTWFyZ2luLCBUb3RhbCBWb3RlcyIsIHBhbGV0dGUgPSAidmlyaWRpcyIpICsgI0kgbGlrZSB2aXJpZGlzCnRtX2JvcmRlcnMoYWxwaGE9LjUpICsKdG1fdGV4dCgiTkFNRSIsIHNpemU9MC44KSArIAp0bV9zdHlsZSgiY2xhc3NpYyIpCmBgYAoKYGBge3J9Cm5oc3RhdGljbWFwCmBgYAoKYGBge3J9CnRtYXBfc2F2ZShuaHN0YXRpY21hcCwgZmlsZW5hbWU9Im5oZGVtcHJpbWFyeS5qcGciKSAKYGBgCgpgYGB7cn0KY2xpbnRvblBhbGV0dGUgPC0gY29sb3JOdW1lcmljKHBhbGV0dGUgPSAiQmx1ZXMiLCBkb21haW49bmhtYXAkQ2xpbnRvblBjdCkgICMgY29sb3IgcGFsZXR0ZSBmb3IgQ2xpbnRvbgpgYGAKCmBgYHtyfQpsaWJyYXJ5KHNjYWxlcykKYGBgCgpgYGB7cn0Kbmhwb3B1cCA8LSBwYXN0ZTAoIkNvdW50eTogIiwgbmhtYXAkTkFNRSwKIiwgU2FuZGVycyAiLCBwZXJjZW50KG5obWFwJFNhbmRlcnNQY3QpLCAiIC0gQ2xpbnRvbiAiLCBwZXJjZW50KG5obWFwJENsaW50b25QY3QpKSAgIyBwb3B1cCBjb250ZW50CmBgYAoKYGBge3J9CiMgYWRkIHRoZSBhcHByb3ByaWF0ZSBwcm9qZWN0aW9uLCBXR1M4NApuaG1hcF9wcm9qZWN0ZWQgPC0gc3A6OnNwVHJhbnNmb3JtKG5obWFwLCAiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSAgCmxlYWZsZXQobmhtYXBfcHJvamVjdGVkKSAlPiUKICBhZGRQcm92aWRlclRpbGVzKCJDYXJ0b0RCLlBvc2l0cm9uIikgJT4lCiAgYWRkUG9seWdvbnMoc3Ryb2tlPUZBTFNFLCAKICAgICAgICAgICAgICBzbW9vdGhGYWN0b3IgPSAwLjIsIAogICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gLjgsIAogICAgICAgICAgICAgIHBvcHVwPW5ocG9wdXAsCiAgICAgICAgICAgICAgY29sb3I9IH5jbGludG9uUGFsZXR0ZShuaG1hcCRDbGludG9uUGN0KSkKYGBgCgpgYGB7cn0Kc2V0d2QoIi9Vc2Vycy9kYW5pZWxsZWZldnJlL0RvY3VtZW50cy9EQVRBXCAxMTAvTkhEZW1QcmltYXJ5L2NvbXB1dGVyd29ybGRybWFwdHV0b3JpYWwvZGF0YSIpCnNjZGF0YSA8LSByaW86OmltcG9ydChzY2RhdGFmaWxlKQpgYGAKCmBgYHtyfQpzY2dlbyA8LSB1c2dlb1t1c2dlb0BkYXRhJFNUQVRFRlA9PSI0NSIsXQpxdG0oc2NnZW8pCmBgYAoKYGBge3J9CmNhbmRpZGF0ZXMgPC0gY29sbmFtZXMoc2NkYXRhWzI6N10pCmZvcihpIGluIDI6Nyl7CiAgaiA9IGkgKyA3CiAgdGVtcCA8LSBzY2RhdGFbW2ldXSAvIHNjZGF0YSRUb3RhbAogIHNjZGF0YVtbal1dIDwtIHRlbXAKICBjb2xuYW1lcyhzY2RhdGEpW2pdIDwtIHBhc3RlMChjb2xuYW1lcyhzY2RhdGEpW2ldLCAiUGN0IikKfSAgCndpbm5lciA8LSBjb2xuYW1lcyhzY2RhdGFbMjo3XSkKYGBgCgpgYGB7cn0KZm9yKGkgaW4gMTpucm93KHNjZGF0YSkpewogIHNjZGF0YSR3aW5uZXJbaV0gPC0gbmFtZXMod2hpY2gubWF4KHNjZGF0YVtpLDI6N10pKQp9CmBgYAoKYGBge3J9CnNldHdkKCIvVXNlcnMvZGFuaWVsbGVmZXZyZS9Eb2N1bWVudHMvREFUQVwgMTEwL05IRGVtUHJpbWFyeS9jb21wdXRlcndvcmxkcm1hcHR1dG9yaWFsL2RhdGEiKQpzY2VkIDwtIHJpbzo6aW1wb3J0KCJTQ2RlZ3JlZS54bHN4IikKYGBgCgpgYGB7cn0Kc3RyKHNjZ2VvJE5BTUUpCmBgYAoKYGBge3J9CnN0cihzY2RhdGEkQ291bnR5KQpgYGAKCmBgYHtyfQojIENoYW5nZSB0aGUgY291bnR5IG5hbWVzIHRvIHBsYWluIGNoYXJhY3RlcnMgaW4gc2NnZW86CnNjZ2VvJE5BTUUgPC0gYXMuY2hhcmFjdGVyKHNjZ2VvJE5BTUUpCiMgT3JkZXIgZWFjaCBkYXRhIHNldCBieSBjb3VudHkgbmFtZQpzY2dlbyA8LSBzY2dlb1tvcmRlcihzY2dlbyROQU1FKSxdCnNjZGF0YSA8LSBzY2RhdGFbb3JkZXIoc2NkYXRhJENvdW50eSksXQojIGNoZWNrIG5hbWUgYW5kIGNvdW50eSBjb2x1bW5zIGFyZSBpZGVudGljYWwKaWYgKGlkZW50aWNhbChzY2dlbyROQU1FLHNjZGF0YSRDb3VudHkgKSkgewpzY21hcCA8LSBtZXJnZShzY2dlbywgc2NkYXRhLCBieS54ID0gIk5BTUUiLCBieS55ID0gIkNvdW50eSIpCn0gZWxzZSB7c3RvcH0KCiMgQ2hhbmdlIHRoZSBjb3VudHkgbmFtZXMgdG8gcGxhaW4gY2hhcmFjdGVycyBpbiBzY2dlbzoKc2NnZW8kTkFNRSA8LSBhcy5jaGFyYWN0ZXIoc2NnZW8kTkFNRSkKCiMgT3JkZXIgZWFjaCBkYXRhIHNldCBieSBjb3VudHkgbmFtZQpzY2dlbyA8LSBzY2dlb1tvcmRlcihzY2dlbyROQU1FKSxdCnNjZGF0YSA8LSBzY2RhdGFbb3JkZXIoc2NkYXRhJENvdW50eSksXQpzdHIoc2NnZW8kTkFNRSkKYGBgCgpgYGB7cn0Kc3RyKHNjZGF0YSRDb3VudHkpCmBgYAoKYGBge3J9CnNjbWFwIDwtIG1lcmdlKHNjZ2VvLCBzY2RhdGEsIGJ5LnggPSAiTkFNRSIsIGJ5LnkgPSAiQ291bnR5IikKYGBgCgpgYGB7cn0KIyBVc2Ugc2FtZSBpbnRlbnNpdHkgZm9yIGFsbCAtIGdldCBtaW5pbXVtIGFuZCBtYXhpbXVtIGZvciB0aGUgdG9wIDMgY29tYmluZWQKbWlucGN0IDwtIG1pbihjKHNjZGF0YSRgRG9uYWxkIEogVHJ1bXBQY3RgLCBzY2RhdGEkYE1hcmNvIFJ1YmlvUGN0YCwgc2NkYXRhJGBUZWQgQ3J1elBjdGApKQptYXhwY3QgPC0gbWF4KGMoc2NkYXRhJGBEb25hbGQgSiBUcnVtcFBjdGAsIHNjZGF0YSRgTWFyY28gUnViaW9QY3RgLCBzY2RhdGEkYFRlZCBDcnV6UGN0YCkpCmBgYAoKYGBge3J9CnRydW1wUGFsZXR0ZSA8LSBjb2xvck51bWVyaWMocGFsZXR0ZSA9ICJQdXJwbGVzIiwgZG9tYWluPWMobWlucGN0LCBtYXhwY3QpKQpydWJpb1BhbGV0dGUgPC0gY29sb3JOdW1lcmljKHBhbGV0dGUgPSAiUmVkcyIsIGRvbWFpbiA9IGMobWlucGN0LCBtYXhwY3QpKQpjcnV6UGFsZXR0ZSA8LSBjb2xvck51bWVyaWMocGFsZXR0ZSA9ICJPcmFuZ2VzIiwgZG9tYWluID0gYyhtaW5wY3QsIG1heHBjdCkpCgp3aW5uZXJQYWxldHRlIDwtIGNvbG9yRmFjdG9yKHBhbGV0dGU9YygiIzk4NGVhMyIsICIjZTQxYTFjIiksIGRvbWFpbiA9IHNjbWFwJHdpbm5lcikKZWRQYWxldHRlIDwtIGNvbG9yTnVtZXJpYyhwYWxldHRlID0gIkJsdWVzIiwgZG9tYWluPXNjbWFwJFBjdENvbGxlZ2VEZWdyZWUpCmBgYAoKYGBge3J9CnNjcG9wdXAgPC0gcGFzdGUwKCI8Yj5Db3VudHk6ICIsIHNjbWFwJE5BTUUsICI8YnIgLz5XaW5uZXI6ICIsIHNjbWFwJHdpbm5lciwgIjwvYj48YnIgLz48YnIgLz5UcnVtcDogIiwgcGVyY2VudChzY21hcCRgRG9uYWxkIEogVHJ1bXBQY3RgKSwgIjxiciAvPlJ1YmlvOiAiLCBwZXJjZW50KHNjbWFwJGBNYXJjbyBSdWJpb1BjdGApLCAiPGJyIC8+Q3J1ejogIiwgcGVyY2VudChzY21hcCRgVGVkIENydXpQY3RgKSwgIjxiciAvPjxiciAvPlBjdCB3IGNvbGxlZ2UgZWQ6ICIsIHNjZWQkUGN0Q29sbGVnZURlZ3JlZSwgIiUgdnMgc3RhdGUtd2lkZSBhdmcgb2YgMjUlIikKYGBgCgpgYGB7cn0Kc2NtYXAgPC0gc3A6OnNwVHJhbnNmb3JtKHNjbWFwLCAiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKQpgYGAKCmBgYHtyfQpsZWFmbGV0KHNjbWFwKSAlPiUKICBhZGRQcm92aWRlclRpbGVzKCJDYXJ0b0RCLlBvc2l0cm9uIikgJT4lCiAgYWRkUG9seWdvbnMoc3Ryb2tlPVRSVUUsCiAgICAgICAgICAgICAgd2VpZ2h0PTEsCiAgICAgICAgICAgICAgc21vb3RoRmFjdG9yID0gMC4yLAogICAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0gLjc1LAogICAgICAgICAgICAgIHBvcHVwPXNjcG9wdXAsIAogICAgICAgICAgICAgIGNvbG9yPSB+d2lubmVyUGFsZXR0ZShzY21hcCR3aW5uZXIpLAogICAgICAgICAgICAgIGdyb3VwPSJXaW5uZXJzIiApICU+JQogICAgYWRkTGVnZW5kKHBvc2l0aW9uPSJib3R0b21sZWZ0IiwgY29sb3JzPWMoIiM5ODRlYTMiLCAiI2U0MWExYyIpLCBsYWJlbHM9YygiVHJ1bXAiLCAiUnViaW8iKSkKYGBgCgpgYGB7cn0Kc2NHT1BtYXAgPC0gbGVhZmxldChzY21hcCkgJT4lCiAgYWRkUHJvdmlkZXJUaWxlcygiQ2FydG9EQi5Qb3NpdHJvbiIpICU+JQogIGFkZFBvbHlnb25zKHN0cm9rZT1UUlVFLAogICAgICAgICAgICAgIHdlaWdodD0xLAogICAgICAgICAgICAgIHNtb290aEZhY3RvciA9IDAuMiwKICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IC43NSwKICAgICAgICAgICAgICBwb3B1cD1zY3BvcHVwLCAKICAgICAgICAgICAgICBjb2xvcj0gfndpbm5lclBhbGV0dGUoc2NtYXAkd2lubmVyKSwKICAgICAgICAgICAgICBncm91cD0iV2lubmVycyIgICkgJT4lIAogICAgYWRkTGVnZW5kKHBvc2l0aW9uPSJib3R0b21sZWZ0IiwgY29sb3JzPWMoIiM5ODRlYTMiLCAiI2U0MWExYyIpLCBsYWJlbHM9YygiVHJ1bXAiLCAiUnViaW8iKSkgICU+JQoKICBhZGRQb2x5Z29ucyhzdHJva2U9VFJVRSwKICAgICB3ZWlnaHQ9MSwKICAgICBzbW9vdGhGYWN0b3IgPSAwLjIsIAogICAgIGZpbGxPcGFjaXR5ID0gLjc1LCAKICAgICBwb3B1cD1zY3BvcHVwLCAKICAgICBjb2xvcj0gfnRydW1wUGFsZXR0ZShzY21hcCRgRG9uYWxkIEogVHJ1bXBQY3RgKSwKICAgICBncm91cD0iVHJ1bXAiKSAlPiUKCiAgYWRkUG9seWdvbnMoc3Ryb2tlPVRSVUUsCiAgICAgICAgICAgICAgd2VpZ2h0PTEsCiAgICAgICAgICAgICAgc21vb3RoRmFjdG9yID0gMC4yLCAKICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IC43NSwgCiAgICAgICAgICAgICAgcG9wdXA9c2Nwb3B1cCwgCiAgICAgICAgICAgICAgY29sb3I9IH5ydWJpb1BhbGV0dGUoc2NtYXAkYE1hcmNvIFJ1YmlvUGN0YCksCiAgICAgICAgICAgICAgZ3JvdXA9IlJ1YmlvIikgJT4lCgogIGFkZFBvbHlnb25zKHN0cm9rZT1UUlVFLAogICAgICAgICAgICAgIHdlaWdodD0xLAogICAgICAgICAgICAgIHNtb290aEZhY3RvciA9IDAuMiwgCiAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAuNzUsIAogICAgICAgICAgICAgIHBvcHVwPXNjcG9wdXAsIAogICAgICAgICAgICAgIGNvbG9yPSB+Y3J1elBhbGV0dGUoc2NtYXAkYFRlZCBDcnV6UGN0YCksCiAgICAgICAgICAgICAgZ3JvdXA9IkNydXoiKSAlPiUKCiAgYWRkUG9seWdvbnMoc3Ryb2tlPVRSVUUsCiAgICAgICAgICAgICAgd2VpZ2h0PTEsCiAgICAgICAgICAgICAgc21vb3RoRmFjdG9yID0gMC4yLCAKICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IC43NSwgCiAgICAgICAgICAgICAgcG9wdXA9c2Nwb3B1cCwgCiAgICAgICAgICAgICAgY29sb3I9IH5lZFBhbGV0dGUoc2NlZCRQY3RDb2xsZWdlRGVncmVlKSwgI3RoaXMgZGF0YSBpcyBpbiB0aGUgc2NlZCB0YWJsZSwgbm90IHNjbWFwcwogICAgICAgICAgICAgIGdyb3VwPSJDb2xsZWdlIGRlZ3MiKSAlPiUKCiAgYWRkTGF5ZXJzQ29udHJvbCgKICAgICAgYmFzZUdyb3Vwcz1jKCJXaW5uZXJzIiwgIlRydW1wIiwgIlJ1YmlvIiwgIkNydXoiLCAiQ29sbGVnZSBkZWdzIiksCiAgICAgIHBvc2l0aW9uID0gImJvdHRvbWxlZnQiLAogICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKQoKIyBOb3cgZGlzcGxheSB0aGUgbWFwCnNjR09QbWFwCmBgYAoK