2 Building Static Maps in R Studio

2.1 Load your libraries and set your working directory

# Load libraries
library(tmap)
library(sf)
library(tidyverse)

If you don’t already have the packages installed, you must install them before loading the libraries; you can install the libraries with the following:

install.packages(c("tmap", "sf", "tidyverse"))

After your libraries are successfully installed and loaded, set your working directory by passing the file path of the directory that contains your data to the setwd function, as in the example below (but note your file path will look different).

# Set your working directory to the directory containing your data
setwd("/Users/adra7980/Documents/git_repositories/gistools_qda/data")

If you don’t know the relevant file path, you can set your working directory manually by opening the Session menu, scrolling down to Set Working Directory, clicking Choose Directory, and then following the prompts.

2.2 Read in a spatial dataset

First, let’s read in our spatial dataset, titled usa_shapefile.shp using the st_read function, and then assigning the spatial dataset to a new object named usa_shapefile

# Read in the shapefile named "usa_shapefile.shp" and assign to new object named "usa_shapefile"
usa_shapefile<-st_read("usa_shapefile.shp")
## Reading layer `usa_shapefile' from data source `/Users/adra7980/Documents/git_repositories/gistools_qda/data/usa_shapefile.shp' using driver `ESRI Shapefile'
## Simple feature collection with 52 features and 3 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -4088650 ymin: -1696697 xmax: 2258200 ymax: 1565782
## projected CRS:  USA_Contiguous_Albers_Equal_Area_Conic

2.3 View the spatial dataset’s attribute table

To view the spatial dataset’s attributes, simply print its name:

usa_shapefile
## Simple feature collection with 52 features and 3 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -4088650 ymin: -1696697 xmax: 2258200 ymax: 1565782
## projected CRS:  USA_Contiguous_Albers_Equal_Area_Conic
## First 10 features:
##    GEOID           name abbrev                       geometry
## 1     23          Maine     ME MULTIPOLYGON (((2217413 111...
## 2     25  Massachusetts     MA MULTIPOLYGON (((2057879 734...
## 3     26       Michigan     MI MULTIPOLYGON (((548934.7 12...
## 4     30        Montana     MT MULTIPOLYGON (((-633753 865...
## 5     32         Nevada     NV MULTIPOLYGON (((-1581791 94...
## 6     34     New Jersey     NJ MULTIPOLYGON (((1727369 428...
## 7     36       New York     NY MULTIPOLYGON (((1977956 675...
## 8     37 North Carolina     NC MULTIPOLYGON (((1192302 -79...
## 9     39           Ohio     OH MULTIPOLYGON (((1085606 548...
## 10    42   Pennsylvania     PA MULTIPOLYGON (((1733137 446...

To view the attribute table in R Studio’s data viewer, pass it to the View function:

View(usa_shapefile)

2.4 Map the spatial dataset

To view render the spatial dataset’s geographic attributes, we can use the tmap package. First, pass the name of the spatial object (usa_shapefile) to the tm_shape function, and then indicate that the spatial attributes are polyons with the tm_polygons function. The two functions should be connected with a + sign

## tmap mode set to plotting
# Use the "tm_shape" and "tm_polygons" function to render the polygons in the spatial dataset
tm_shape(usa_shapefile)+
  tm_polygons()

The polygons (here, US states) will be printed in the “Plots” tab of the R Studio interface.

For convenience, we can assign the basic map of the shapefile’s polygons to its own object; here we’ll assign it to an object named usa_map.

## tmap mode set to plotting
# Assigns map of "usa_shapefile" geographic attributes to a new object named "usa_map"
usa_map<-tm_shape(usa_shapefile)+
            tm_polygons()

Now, we simply have to print usa_map to view the geographic attributes of usa_shapefile.

## tmap mode set to plotting
usa_map

2.5 Read in the tabular dataset containing the information to map

Now, let’s read in our CSV file, which contains the state government data we’d like to map. To do so, we can pass the name of the CSV file to the read_csv function. We’ll assign the CSV file to an object named usa_trifecta

# Reads in "usa_trifecta.csv" and assigns the data to an object named "usa_trifecta"
usa_trifecta<-read_csv("usa_trifecta.csv")
## 
## ── Column specification ─────────────────────────────────────────────────────────────────────────────────────────
## cols(
##   GEOID = col_double(),
##   NAME = col_character(),
##   abbrev = col_character(),
##   Composition = col_character()
## )

To open the dataset, type the name of the object in the console (or run it from your script):

usa_trifecta
## # A tibble: 50 x 4
##    GEOID NAME        abbrev Composition        
##    <dbl> <chr>       <chr>  <chr>              
##  1     1 Alabama     AL     Republican Trifecta
##  2     2 Alaska      AK     Divided Government 
##  3     4 Arizona     AZ     Republican Trifecta
##  4     5 Arkansas    AR     Republican Trifecta
##  5     6 California  CA     Democratic Trifecta
##  6     8 Colorado    CO     Democratic Trifecta
##  7     9 Connecticut CT     Democratic Trifecta
##  8    10 Delaware    DE     Democratic Trifecta
##  9    12 Florida     FL     Republican Trifecta
## 10    13 Georgia     GA     Republican Trifecta
## # … with 40 more rows

To view the CSV data in R Studio’s data viewer, pass the object’s name to the View function:

View(usa_trifecta)

2.6 Merge data

Now, let’s merge our tabular CSV data into the spatial dataset, and assign the merged dataset to a new object named usa_shapefile_trifecta. To do so, we’ll use the right_join function. The first argument is the spatial object (usa_shapefile), while the second argument is the tabular data object (usa_trifecta). The third argument, by="abbrev indicates that the two datasets are to be joined based on the information contained in the abbrev field (i.e. 2-letter state codes).

By using right_join, we’re specifying that we want to keep all the records in usa_trifecta, and discard any records that are in usa_shapefile but not usa_trifecta. This effectively removes DC and Puerto Rico from our joined dataset, which is appropriate in the context of this exercise, since these are not currently states.

# Joins the "usa_trifecta" data to "usa_shapefile" based on the "abbrev" field that is in both datasets; the joined dataset is assigned to a new object named "usa_shapefile_trifecta"
usa_shapefile_trifecta<-right_join(usa_shapefile, usa_trifecta, by="abbrev" )

Before moving on, observe the contents of usa_shapefile_trifecta to ensure that the join has succeeded.

# Prints contents of "usa_shapefile_trifecta"
usa_shapefile_trifecta
## Simple feature collection with 50 features and 6 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -4088650 ymin: -1696697 xmax: 2258200 ymax: 1565782
## projected CRS:  USA_Contiguous_Albers_Equal_Area_Conic
## First 10 features:
##    GEOID.x           name abbrev GEOID.y           NAME         Composition                       geometry
## 1       23          Maine     ME      23          Maine Democratic Trifecta MULTIPOLYGON (((2217413 111...
## 2       25  Massachusetts     MA      25  Massachusetts  Divided Government MULTIPOLYGON (((2057879 734...
## 3       26       Michigan     MI      26       Michigan  Divided Government MULTIPOLYGON (((548934.7 12...
## 4       30        Montana     MT      30        Montana Republican Trifecta MULTIPOLYGON (((-633753 865...
## 5       32         Nevada     NV      32         Nevada Democratic Trifecta MULTIPOLYGON (((-1581791 94...
## 6       34     New Jersey     NJ      34     New Jersey Democratic Trifecta MULTIPOLYGON (((1727369 428...
## 7       36       New York     NY      36       New York Democratic Trifecta MULTIPOLYGON (((1977956 675...
## 8       37 North Carolina     NC      37 North Carolina  Divided Government MULTIPOLYGON (((1192302 -79...
## 9       39           Ohio     OH      39           Ohio Republican Trifecta MULTIPOLYGON (((1085606 548...
## 10      42   Pennsylvania     PA      42   Pennsylvania  Divided Government MULTIPOLYGON (((1733137 446...

2.7 Map the trifecta data

Now, we’re ready to map our data. Let’s start with a very rough map, which we’ll assign to an object named usa_trifecta_map. As before, we declare the spatial object that is the basis for the map (here, usa_shapefile_trifecta) using the tm_shape function. Then, we declare the column to be mapped (here, Composition) within the tm_polygons function:

## tmap mode set to plotting
# Makes basic map of categories of interest
usa_trifecta_map<-tm_shape(usa_shapefile_trifecta)+
                    tm_polygons(col="Composition")
# Prints map
usa_trifecta_map

This default color scheme is not very intuitive, so let’s change it, such that Democratic trifectas are dark blue, Republican trifectas are dark red, and states with divided government are beige.

To work intuitively with colors when dealing with categorical data, it is helpful to first declare the categorical data as a factor variable; specify the levels in the order you want your categories in the legend.

## tmap mode set to plotting
# Sets composition variable as factor
usa_shapefile_trifecta<-usa_shapefile_trifecta %>% 
                          mutate(Composition=factor(Composition, levels=c("Democratic Trifecta", "Republican Trifecta", "Divided Government")))

Now, create a vector of colors that corresponds to these levels, and assign this vector to an object named ` colors. The first color in the colors vector will be used for the “Democratic Trifecta” category, the second color for “Republican Trifecta”, and so on. The color codes can be found in this helpful color cheatsheet.

Set the colors vector equal to palette within the tm_polygons function:

## tmap mode set to plotting
# Maps data with custom colors; also, note the changed order in the legend
colors<-c("navy", "red3", "seashell")
usa_trifecta_map<-tm_shape(usa_shapefile_trifecta)+
                    tm_polygons(col="Composition", 
                                palette=colors)

usa_trifecta_map

Now, let’s shift the legend, remove the bounding box, remove the legend title, and add a title for the map.

## tmap mode set to plotting
usa_trifecta_map<-usa_trifecta_map<-tm_shape(usa_shapefile_trifecta)+ # indicates spatial object to map
                                      tm_polygons(col="Composition", # indicates column with data to map
                                                  palette=colors,    # sets colors
                                                  title="")+         # removes legend title
                                    tm_layout(legend.position = c("left", "center"), # sets legend position
                                              frame=FALSE,          # removes map frame
                                              main.title="Partisan Composition of State Governments, 2022", # sets map title
                                              main.title.size=1, # sets map title size
                                              main.title.position="center") # sets map title position
                    

usa_trifecta_map

Now, let’s add a credits section, to indicate the map’s author and give credit to the source of the data. We can do so with the tm_credits function:

usa_trifecta_map<-usa_trifecta_map+
                  tm_credits("Map Author: Aditya Ranganath\nSource: Ballotpedia", size=0.5) # sets map credits and size

usa_trifecta_map

2.8 Summary Script

The following presents all of the steps we took to create our print map in one streamlined script; it assumes that the libraries are loaded, and that you are in the working directory that contains your data:

# Read in shapefile and assign to object named "usa_shapefile"
usa_shapefile<-st_read("usa_shapefile.shp")
## Reading layer `usa_shapefile' from data source `/Users/adra7980/Documents/git_repositories/gistools_qda/data/usa_shapefile.shp' using driver `ESRI Shapefile'
## Simple feature collection with 52 features and 3 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -4088650 ymin: -1696697 xmax: 2258200 ymax: 1565782
## projected CRS:  USA_Contiguous_Albers_Equal_Area_Conic
# Read in tabular CSV data containing data to map and assign to object named "usa_trifecta"
usa_trifecta<-read_csv("usa_trifecta.csv")

# Join "usa_trifecta" to "usa_shapefile" using "abbrev" as the join variable; use "right_join" to only keep records from "usa_trifecta" (which effectively deletes PR and DC); assign the joined dataset to a new object named "usa_shapefile_trifecta"
usa_shapefile_trifecta<-right_join(usa_shapefile, usa_trifecta, by="abbrev")

# Set the composition variable as a factor variable; specify the levels in the order you want them to appear in the legend
usa_shapefile_trifecta<-usa_shapefile_trifecta %>% 
                          mutate(Composition=factor(Composition, levels=c("Democratic Trifecta", "Republican Trifecta", "Divided Government"))) 

# create a color vector; the first color will be used to map the first level, second category to map the second level, and so on:
colors<-c("navy", "red3", "seashell")

# Use tmap to create the map, and assign the map to an object named "usa_trifecta_map"
usa_trifecta_map<-tm_shape(usa_shapefile_trifecta)+ # indicate sf object to be mapped
                      tm_polygons(col="Composition", # specify column to be mapped
                                  palette=colors,    # sets tolors
                                  title="")+         # specifies no title for legend
                      tm_layout(legend.position = c("left", "center"), # sets legend position
                                frame=FALSE,         # removes map frame/bounding box
                                main.title="Partisan Composition of State Governments, 2022", # sets map title
                                main.title.size=1,   # sets map title size
                                main.title.position="center")+ # sets map title position
                       tm_credits("Map Author: Aditya Ranganath\nSource: Ballotpedia", size=0.5) # adds credits
                    
# Prints map
usa_trifecta_map