Ally Panavong PLS 300-01

Gerrymandering Analysis of Michigan Districts Between the 2010-2020 House of Representatives Redistricting

Hypothesis: Districts of Michigan’s top 3 universities were significantly gerrymandered between the 2010-2020 House of Representatives redistricting, as measured by the convex hull and Polsby-Popper scores.

Map of the 2010 US House Districts

library(sf)
## Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE
library(leaflet)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## âś” dplyr     1.1.4     âś” readr     2.1.5
## âś” forcats   1.0.0     âś” stringr   1.5.1
## âś” ggplot2   3.5.1     âś” tibble    3.2.1
## âś” lubridate 1.9.3     âś” tidyr     1.3.1
## âś” purrr     1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## âś– dplyr::filter() masks stats::filter()
## âś– dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
### read in 2010 districts
mi_house_2010<-st_read("Michigan_2010_USHouse_Districts.geojson")
## Reading layer `Michigan%20U.S.%20Congressional%20Districts%2C%202010' from data source `/home/panavona/PLS300/gerrymandering final project/Michigan_2010_USHouse_Districts.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 14 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -90.4184 ymin: 41.69612 xmax: -82.41865 ymax: 48.26268
## Geodetic CRS:  WGS 84
### visualize 2010 districts
mi_house_2010<-mi_house_2010 %>%
  mutate(popup_content = paste("<strong>District:</strong> ", DISTRICT,
                               "<br><strong>Area(sqmi):</strong> ", AREA_SQ_MI))
                      
leaflet() %>%
  addPolygons(data=mi_house_2010, popup=~popup_content, label=~DISTRICT) %>%
  addTiles()

Individual Districts and Convex Hull Scores

## use district 12 University of Michigan, Ann Arbor
district_12<-mi_house_2010 %>%
  filter(LABEL=="12")

leaflet() %>%
  addPolygons(data=district_12, popup=~popup_content, label=~DISTRICT) %>%
  addTiles()
# create convex hull boundary
district_12 <- district_12 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_12, popup=~popup_content) %>%
  addPolygons(data = district_12$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_12)

convex_hull_area <- st_area(district_12$convex_hull)

# convex hull score 
boundary_area / convex_hull_area
## 0.6536457 [1]

Explain score…

## use district 08 Michigan State University, East Lansing
district_08<-mi_house_2010 %>%
  filter(LABEL=="08")

leaflet() %>%
  addPolygons(data=district_08, popup=~popup_content, label=~DISTRICT) %>%
  addTiles()
# create convex hull boundary
district_08 <- district_08 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_08, popup=~popup_content) %>%
  addPolygons(data = district_08$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_08)

convex_hull_area <- st_area(district_08$convex_hull)

# convex hull score 
boundary_area / convex_hull_area
## 0.76258 [1]

Explain score…

## use district 13 Wayne State University, Detroit
district_13<-mi_house_2010 %>%
  filter(LABEL=="13")

leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content, label=~DISTRICT) %>%
  addTiles()
# create convex hull boundary
district_13 <- district_13 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content) %>%
  addPolygons(data = district_13$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_13)
convex_hull_area <- st_area(district_13$convex_hull)

# convex hull score 
boundary_area / convex_hull_area
## 0.6192211 [1]

Explain score…

Combined Map Convex Hull Scores

### combine districts 08, 12, & 13 convex hull
districts_convex_hull <- mi_house_2010 %>%
  filter(LABEL %in% c("08", "12", "13")) %>%
  mutate(convex_hull=st_convex_hull(geometry), 
         area=st_area(geometry),
         hull_area=st_area(convex_hull),
         convex_hull_score=as.numeric(area / hull_area))

## add color coding palette
pal <- colorNumeric("YlOrRd", domain=districts_convex_hull$convex_hull_score)

districts_convex_hull <- districts_convex_hull %>%
  mutate(popup_content=paste("<strong>District:</strong>", DISTRICT,
                             "<br><strong>Convex Hull Score:</strong>", round(convex_hull_score, 3)))

## create map
leaflet() %>%
  addTiles() %>%
  addPolygons(data=districts_convex_hull,
              fillColor=~pal(convex_hull_score),
              color="black",
              weight=1,
              fillOpacity=0.7,
              popup=~popup_content,
              label=~DISTRICT)

Summarize compactness and using convex hull scores to analyze gerrymandering during the 2010 House redistricting…

Individual Districts and Polsby Popper Scores

## use district 12 University of Michigan, Ann Arbor
district_12$area <- st_area(district_12)
district_12$perimeter <- st_length(st_boundary(district_12))

## from the formula  
district_12$radius <-district_12$perimeter / (2 * pi)


## finding the centroid of the district:
district_12$centroid<-st_centroid(district_12)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_12, popup=~popup_content) %>%
  addMarkers(data=district_12$centroid) %>%
  addTiles() 
district_12$circle <- st_buffer(district_12$centroid, dist = district_12$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_12, popup=~popup_content) %>%
  addPolygons(data=district_12$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_12$area) / (district_12$perimeter^2)


# the approximation of Polsby-Popper
district_12$area/st_area(district_12$circle)
## 0.1305423 [1]

Explain score…

### use district 08 Michigan State University, East Lansing
district_08$area <- st_area(district_08)
district_08$perimeter <- st_length(st_boundary(district_08))

## from the formula  
district_08$radius <-district_08$perimeter / (2 * pi)


## finding the centroid of the district:
district_08$centroid<-st_centroid(district_08)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_08, popup=~popup_content) %>%
  addMarkers(data=district_08$centroid) %>%
  addTiles() 
district_08$circle <- st_buffer(district_08$centroid, dist = district_08$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_08, popup=~popup_content) %>%
  addPolygons(data=district_08$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_08$area) / (district_08$perimeter^2)


# the approximation of Polsby-Popper
district_08$area/st_area(district_08$circle)
## 0.3627543 [1]

Explain score…

### use district 13 Wayne State University, Detroit
district_13$area <- st_area(district_13)
district_13$perimeter <- st_length(st_boundary(district_13))

## from the formula  
district_13$radius <-district_13$perimeter / (2 * pi)


## finding the centroid of the district:
district_13$centroid<-st_centroid(district_13)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content) %>%
  addMarkers(data=district_13$centroid) %>%
  addTiles() 
district_13$circle <- st_buffer(district_13$centroid, dist = district_13$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content) %>%
  addPolygons(data=district_13$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_13$area) / (district_13$perimeter^2)


# the approximation of Polsby-Popper
district_13$area/st_area(district_13$circle)
## 0.1754582 [1]

Explain score…

Combined Map Polsby-Popper Scores

### combine districts 08, 12, & 13 polsby-popper
districts_pp <- mi_house_2010 %>%
  filter(LABEL %in% c("08", "12", "13"))

districts_pp <- districts_pp %>%
  mutate(
    area=st_area(geometry),
    perimeter=st_length(st_boundary(geometry)),
    polsby_popper=as.numeric((4 * pi * area) / (perimeter^2)))

## add color coding palette
pal <- colorNumeric("YlOrRd", domain=districts_pp$polsby_popper)

districts_pp <- districts_pp %>%
  mutate(popup_content=paste("<strong>District:</strong>", DISTRICT,
                            "<br><strong>Polsby-Popper Score:</strong>", round(polsby_popper, 3)))

## create map
leaflet() %>%
  addTiles() %>%
  addPolygons(data=districts_pp,
              fillColor=~pal(polsby_popper),
              color="black",
              weight= 1,
              fillOpacity= 0.7,
              popup=~popup_content,
              label=~DISTRICT)

Summarize compactness and using Polsby-Popper scores to analyze gerrymandering during the 2010 House redistricting… Do the convex hull and Polsby-Poppers support each other in indicating gerrymandering?

Map of the 2020 US House Districts

mi_house_2020<-st_read("Michigan_2020_USHouse_Districts.geojson")
## Reading layer `Michigan_U.S._Congressional_Districts_2021' from data source 
##   `/home/panavona/PLS300/gerrymandering final project/Michigan_2020_USHouse_Districts.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 13 features and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -90.41828 ymin: 41.69612 xmax: -82.41838 ymax: 48.26268
## Geodetic CRS:  WGS 84
### visualize 2020 districts
leaflet() %>%
  addPolygons(data=mi_house_2020, popup=~NAME) %>%
  addTiles()
mi_house_2020<-mi_house_2020 %>%
  mutate(popup_content = paste("<strong>District:</strong> ", NAME))

Individual Districts and Convex Hull Scores

## use district 06 University of Michigan, Ann Arbor
district_06<-mi_house_2020 %>%
  filter(LABEL=="06")

leaflet() %>%
  addPolygons(data=district_06, popup=~NAME) %>%
  addTiles()
# create convex hull boundary
district_06 <- district_06 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_06, popup=~LABEL) %>%
  addPolygons(data = district_06$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_06)

convex_hull_area <- st_area(district_06$convex_hull)


# convex hull score 
boundary_area / convex_hull_area
## 0.7262418 [1]

Explain score…

## use district 07 Michigan State University, East Lansing
district_07<-mi_house_2020 %>%
  filter(LABEL=="07")

leaflet() %>%
  addPolygons(data=district_07, popup=~NAME) %>%
  addTiles()
# create convex hull boundary
district_07 <- district_07 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_07, popup=~NAME) %>%
  addPolygons(data = district_07$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_07)

convex_hull_area <- st_area(district_07$convex_hull)

# convex hull score 
boundary_area / convex_hull_area
## 0.8966061 [1]

Explain score…

# use district 13 Wayne State University, Detroit
district_13<-mi_house_2020 %>%
  filter(LABEL=="13")

leaflet() %>%
  addPolygons(data=district_13, popup=~NAME) %>%
  addTiles()
# create convex hull boundary
district_13 <- district_13 %>%
  mutate(convex_hull= st_convex_hull(geometry))


# run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~NAME) %>%
  addPolygons(data = district_13$convex_hull, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
boundary_area <- st_area(district_13)

convex_hull_area <- st_area(district_13$convex_hull)

# convex hull score 
boundary_area / convex_hull_area
## 0.65377 [1]

Explain score…

Combined Map Convex Hull Scores

### combine districts 06, 07, & 13 convex hull
districts_convex_hull <- mi_house_2020 %>%
  filter(LABEL %in% c("06", "07", "13")) %>%
  mutate(convex_hull=st_convex_hull(geometry), 
         area=st_area(geometry),
         hull_area=st_area(convex_hull),
         convex_hull_score=as.numeric(area / hull_area))

## add color coding palette
pal <- colorNumeric("YlOrRd", domain=districts_convex_hull$convex_hull_score)

districts_convex_hull <- districts_convex_hull %>%
  mutate(popup_content=paste("<strong>District:</strong>", NAME,
                             "<br><strong>Convex Hull Score:</strong>", round(convex_hull_score, 3)))

## create map
leaflet() %>%
  addTiles() %>%
  addPolygons(data=districts_convex_hull,
              fillColor=~pal(convex_hull_score),
              color="black",
              weight=1,
              fillOpacity=0.7,
              popup=~popup_content,
              label=~NAME)

Summarize compactness and using convex hull scores to analyze gerrymandering during the 2010 House redistricting…

Individual Districts and Polsby Popper Scores

## use district 06 University of Michigan, Ann Arbor
district_06$area <- st_area(district_06)
district_06$perimeter <- st_length(st_boundary(district_06))

## from the formula  
district_06$radius <-district_06$perimeter / (2 * pi)


## finding the centroid of the district:
district_06$centroid<-st_centroid(district_06)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_06, popup=~popup_content) %>%
  addMarkers(data=district_12$centroid) %>%
  addTiles() 
district_06$circle <- st_buffer(district_06$centroid, dist = district_06$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_06, popup=~popup_content) %>%
  addPolygons(data=district_06$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_06$area) / (district_06$perimeter^2)


# the approximation of Polsby-Popper
district_06$area/st_area(district_06$circle)
## 0.2475566 [1]

Explain score…

### use district 07 Michigan State University, East Lansing
district_07$area <- st_area(district_07)
district_07$perimeter <- st_length(st_boundary(district_07))

## from the formula  
district_07$radius <-district_07$perimeter / (2 * pi)


## finding the centroid of the district:
district_07$centroid<-st_centroid(district_07)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_07, popup=~popup_content) %>%
  addMarkers(data=district_07$centroid) %>%
  addTiles() 
district_07$circle <- st_buffer(district_07$centroid, dist = district_07$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_07, popup=~popup_content) %>%
  addPolygons(data=district_07$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_08$area) / (district_07$perimeter^2)


# the approximation of Polsby-Popper
district_07$area/st_area(district_07$circle)
## 0.5512408 [1]

Explain score…

### use district 13 Wayne State University, Detroit
district_13$area <- st_area(district_13)
district_13$perimeter <- st_length(st_boundary(district_13))

## from the formula  
district_13$radius <-district_13$perimeter / (2 * pi)


## finding the centroid of the district:
district_13$centroid<-st_centroid(district_13)
## Warning: st_centroid assumes attributes are constant over geometries
## run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content) %>%
  addMarkers(data=district_13$centroid) %>%
  addTiles() 
district_13$circle <- st_buffer(district_13$centroid, dist = district_13$radius)

## run these lines together
leaflet() %>%
  addPolygons(data=district_13, popup=~popup_content) %>%
  addPolygons(data=district_13$circle, color = "red", weight = 2, dashArray = "5, 5", 
              fillOpacity = 0.3, fillColor = "red") %>%
  addTiles()
polsby <- (4 * pi * district_13$area) / (district_13$perimeter^2)


# the approximation of Polsby-Popper
district_13$area/st_area(district_13$circle)
## 0.2084315 [1]

Explain score…

Combined Map Polsby-Popper Scores

### combine districts 06, 07, & 13 polsby-popper
districts_pp <- mi_house_2020 %>%
  filter(LABEL %in% c("06", "07", "13"))

districts_pp <- districts_pp %>%
  mutate(
    area=st_area(geometry),
    perimeter=st_length(st_boundary(geometry)),
    polsby_popper=as.numeric((4 * pi * area) / (perimeter^2)))

## add color coding palette
pal <- colorNumeric("YlOrRd", domain=districts_pp$polsby_popper)

districts_pp <- districts_pp %>%
  mutate(popup_content=paste("<strong>Name:</strong>", NAME,
                             "<br><strong>Polsby-Popper Score:</strong>", round(polsby_popper, 3)))

## create map
leaflet() %>%
  addTiles() %>%
  addPolygons(data=districts_pp,
              fillColor=~pal(polsby_popper),
              color="black",
              weight= 1,
              fillOpacity= 0.7,
              popup=~popup_content,
              label=~NAME)

Summarize compactness and using Polsby-Popper scores to analyze gerrymandering during the 2010 House redistricting… Do the convex hull and Polsby-Poppers support each other in indicating gerrymandering?

Compare the results of the measures from 2010 and 2020. Why are convex hull and Polsby-Popper scores used to measure gerrymandering? Why would these districts be gerrymandered? (home to top 3 largest universities)