This is a brief script to calculate the diversity of micro- and metro-SAs using ACS data, the R tidycensus library, and Simpson’s Diversity Index via the R vegan library. Then it shows the top 10 MSAs by their SDI. Then we compute some SDIs of other geographic divisions.
library(tidyverse)
library(tidycensus)
library(vegan)
library(knitr)
Now get some values for population by ethnicity. The variable names represent the following:
race <- get_acs(geography = "metropolitan statistical area/micropolitan statistical area", variables = c("B03002_001","B03002_003","B03002_004","B03002_005","B03002_006","B03002_007","B03002_008","B03002_009","B03002_012"))
race <- select(race,-c(moe))
races <- spread(race,variable,estimate)
Next calculate the Simpson Diversity Index, or the Herfindahl–Hirschman index (HHI). Essentially, this index measures the probability that two specimens taken from the population will be of different type.
races$sdi <- diversity(races[,4:11],"simpson")
races %>%
top_n(10) %>%
arrange(desc(sdi)) %>%
select(NAME, B03002_001, sdi) %>%
kable(digits=3, col.names = c("MSA","Total population","SDI"), format.args = list(big.mark = ","))
| MSA | Total population | SDI |
|---|---|---|
| Hilo, HI Micro Area | 196,325 | 0.778 |
| Kahului-Wailuku-Lahaina, HI Metro Area | 164,180 | 0.767 |
| Kapaa, HI Micro Area | 71,093 | 0.756 |
| Vallejo-Fairfield, CA Metro Area | 434,981 | 0.738 |
| Urban Honolulu, HI Metro Area | 990,060 | 0.738 |
| San Francisco-Oakland-Hayward, CA Metro Area | 4,641,820 | 0.720 |
| Lumberton, NC Micro Area | 134,187 | 0.719 |
| San Jose-Sunnyvale-Santa Clara, CA Metro Area | 1,969,897 | 0.703 |
| Stockton-Lodi, CA Metro Area | 724,153 | 0.696 |
| Houston-The Woodlands-Sugar Land, TX Metro Area | 6,636,208 | 0.693 |
Lots of places with a fairly small population. What about the top 10 over some arbitrary total, like a million and one people?
races %>%
filter(B03002_001 >= 1000001) %>%
top_n(10) %>%
arrange(desc(sdi)) %>%
select(NAME, B03002_001, sdi) %>%
kable(digits=3, col.names = c("MSA","Total population","SDI"), format.args = list(big.mark = ","))
| MSA | Total population | SDI |
|---|---|---|
| San Francisco-Oakland-Hayward, CA Metro Area | 4,641,820 | 0.720 |
| San Jose-Sunnyvale-Santa Clara, CA Metro Area | 1,969,897 | 0.703 |
| Houston-The Woodlands-Sugar Land, TX Metro Area | 6,636,208 | 0.693 |
| Washington-Arlington-Alexandria, DC-VA-MD-WV Metro Area | 6,090,196 | 0.690 |
| Las Vegas-Henderson-Paradise, NV Metro Area | 2,112,436 | 0.689 |
| New York-Newark-Jersey City, NY-NJ-PA Metro Area | 20,192,042 | 0.685 |
| Los Angeles-Long Beach-Anaheim, CA Metro Area | 13,261,538 | 0.678 |
| Dallas-Fort Worth-Arlington, TX Metro Area | 7,104,415 | 0.665 |
| Miami-Fort Lauderdale-West Palm Beach, FL Metro Area | 6,019,790 | 0.664 |
| San Diego-Carlsbad, CA Metro Area | 3,283,665 | 0.659 |
Let’s take a look by county and do it all again.
race <- get_acs(geography = "county", variables = c("B03002_001","B03002_003","B03002_004","B03002_005","B03002_006","B03002_007","B03002_008","B03002_009","B03002_012"))
race <- select(race,-c(moe))
races <- spread(race,variable,estimate)
races$sdi <- diversity(races[,4:11],"simpson")
races %>%
filter(B03002_001 >= 200001) %>%
top_n(10) %>%
arrange(desc(sdi)) %>%
select(NAME, B03002_001, sdi) %>%
kable(digits=3, col.names = c("County","Total population","SDI"), format.args = list(big.mark = ","))
| County | Total population | SDI |
|---|---|---|
| Queens County, New York | 2,339,280 | 0.764 |
| Alameda County, California | 1,629,615 | 0.749 |
| Fort Bend County, Texas | 711,421 | 0.745 |
| Solano County, California | 434,981 | 0.738 |
| Honolulu County, Hawaii | 990,060 | 0.738 |
| Kings County, New York | 2,635,121 | 0.726 |
| Gwinnett County, Georgia | 889,954 | 0.722 |
| Montgomery County, Maryland | 1,039,198 | 0.708 |
| Sacramento County, California | 1,495,400 | 0.704 |
| San Mateo County, California | 763,450 | 0.703 |
Or congressional districts with the highest diversity:
race <- get_acs(geography = "congressional district", variables = c("B03002_001","B03002_003","B03002_004","B03002_005","B03002_006","B03002_007","B03002_008","B03002_009","B03002_012"))
race <- select(race,-c(moe))
races <- spread(race,variable,estimate)
races$sdi <- diversity(races[,4:11],"simpson")
races %>%
#filter(B03002_001 >= 200001) %>%
top_n(10) %>%
arrange(desc(sdi)) %>%
select(NAME, B03002_001, sdi) %>%
kable(digits=3, col.names = c("Congressional district","Total population","SDI"), format.args = list(big.mark = ","))
| Congressional district | Total population | SDI |
|---|---|---|
| Congressional District 2 (115th Congress), Hawaii | 710,433 | 0.782 |
| Congressional District 13 (115th Congress), California | 750,102 | 0.761 |
| Congressional District 6 (115th Congress), California | 743,423 | 0.742 |
| Congressional District 37 (115th Congress), California | 721,893 | 0.726 |
| Congressional District 15 (115th Congress), California | 764,963 | 0.726 |
| Congressional District 47 (115th Congress), California | 717,209 | 0.721 |
| Congressional District 7 (115th Congress), Massachusetts | 781,304 | 0.719 |
| Congressional District 22 (115th Congress), Texas | 844,913 | 0.715 |
| Congressional District 14 (115th Congress), California | 750,274 | 0.712 |
| Congressional District 10 (115th Congress), Florida | 787,875 | 0.711 |
and the districts with the lowest:
races %>%
top_n(-10) %>%
arrange(sdi) %>%
select(NAME, B03002_001, sdi) %>%
kable(digits=3, col.names = c("Congressional district","Total population","SDI"), format.args = list(big.mark = ","))
| Congressional district | Total population | SDI |
|---|---|---|
| Resident Commissioner District (at Large) (115th Congress), Puerto Rico | 3,468,963 | 0.021 |
| Congressional District 5 (115th Congress), Kentucky | 706,248 | 0.083 |
| Congressional District 6 (115th Congress), Ohio | 703,764 | 0.106 |
| Congressional District 2 (115th Congress), Maine | 655,084 | 0.112 |
| Congressional District 1 (115th Congress), West Virginia | 615,449 | 0.125 |
| Congressional District (at Large) (115th Congress), Vermont | 624,636 | 0.130 |
| Congressional District 1 (115th Congress), Maine | 675,074 | 0.134 |
| Congressional District 3 (115th Congress), West Virginia | 597,674 | 0.134 |
| Congressional District 9 (115th Congress), Pennsylvania | 694,033 | 0.137 |
| Congressional District 18 (115th Congress), Pennsylvania | 704,815 | 0.141 |
How does diversity of a congressional district compare to its political leaning? Let’s use data from the Cook Political Report. First we need to do some manipulation to get the Census’s district IDs to match Cook’s in order to properly join the tables.
races$nums <- str_extract(races$NAME, " \\d\\d? ") %>% str_trim()
races$nums <- sprintf("%02d", as.numeric(races$nums))
races$nums[is.na(races$nums)] <- "AL"
races <- races %>%
mutate(states = state.abb[match(str_extract(NAME, '\\b[^,]+$'),state.name)]) %>%
mutate(Dist = str_c(states, nums, sep = "-"))
cook <- read.csv("data-5vPn3.csv", header=TRUE)
cds <- inner_join(cook, races)
cds %>%
top_n(20, sdi) %>%
arrange(desc(sdi)) %>%
select(NAME, Incumbent, B03002_001, sdi, PVI) %>%
kable(digits=3, col.names = c("Congressional district","Member","Total population","SDI","PVI"), format.args = list(big.mark = ","))
| Congressional district | Member | Total population | SDI | PVI |
|---|---|---|---|---|
| Congressional District 2 (115th Congress), Hawaii | Tulsi Gabbard (D) | 710,433 | 0.782 | D+19 |
| Congressional District 13 (115th Congress), California | Barbara Lee (D) | 750,102 | 0.761 | D+40 |
| Congressional District 6 (115th Congress), California | Doris Matsui (D) | 743,423 | 0.742 | D+21 |
| Congressional District 37 (115th Congress), California | Karen Bass (D) | 721,893 | 0.726 | D+37 |
| Congressional District 15 (115th Congress), California | Eric Swalwell (D) | 764,963 | 0.726 | D+20 |
| Congressional District 47 (115th Congress), California | Alan Lowenthal (D) | 717,209 | 0.721 | D+13 |
| Congressional District 7 (115th Congress), Massachusetts | Ayanna Pressley (D) | 781,304 | 0.719 | D+34 |
| Congressional District 22 (115th Congress), Texas | Pete Olson (R) | 844,913 | 0.715 | R+10 |
| Congressional District 14 (115th Congress), California | Jackie Speier (D) | 750,274 | 0.712 | D+27 |
| Congressional District 10 (115th Congress), Florida | Val Demings (D) | 787,875 | 0.711 | D+11 |
| Congressional District 9 (115th Congress), California | Jerry McNerney (D) | 750,185 | 0.708 | D+8 |
| Congressional District 16 (115th Congress), New York | Eliot Engel (D) | 745,855 | 0.706 | D+24 |
| Congressional District 5 (115th Congress), New York | Gregory Meeks (D) | 784,341 | 0.704 | D+37 |
| Congressional District 27 (115th Congress), California | Judy Chu (D) | 719,377 | 0.703 | D+16 |
| Congressional District 9 (115th Congress), Washington | Adam Smith (D) | 726,425 | 0.702 | D+21 |
| Congressional District 7 (115th Congress), New York | Nydia Velazquez (D) | 750,580 | 0.700 | D+38 |
| Congressional District 7 (115th Congress), Georgia | Rob Woodall (R) | 778,970 | 0.699 | R+9 |
| Congressional District 39 (115th Congress), California | Gil Cisneros (D) | 726,854 | 0.699 | EVEN |
| Congressional District 53 (115th Congress), California | Susan Davis (D) | 761,273 | 0.699 | D+14 |
| Congressional District 11 (115th Congress), Virginia | Gerry Connolly (D) | 787,515 | 0.699 | D+15 |
Most, but not all, diverse districts lean Democratic. What about the 20 least diverse districts?
cds %>%
top_n(-20, sdi) %>%
arrange(sdi) %>%
select(NAME, Incumbent, B03002_001, sdi, PVI) %>%
kable(digits=3, col.names = c("Congressional district","Member","Total population","SDI","PVI"), format.args = list(big.mark = ","))
| Congressional district | Member | Total population | SDI | PVI |
|---|---|---|---|---|
| Congressional District 5 (115th Congress), Kentucky | Hal Rogers (R) | 706,248 | 0.083 | R+31 |
| Congressional District 6 (115th Congress), Ohio | Bill Johnson (R) | 703,764 | 0.106 | R+16 |
| Congressional District 2 (115th Congress), Maine | Jared Golden (D) | 655,084 | 0.112 | R+2 |
| Congressional District 1 (115th Congress), West Virginia | David McKinley (R) | 615,449 | 0.125 | R+19 |
| Congressional District 1 (115th Congress), Maine | Chellie Pingree (D) | 675,074 | 0.134 | D+8 |
| Congressional District 3 (115th Congress), West Virginia | Carol Miller (R) | 597,674 | 0.134 | R+23 |
| Congressional District 9 (115th Congress), Pennsylvania | Dan Meuser (R) | 694,033 | 0.137 | R+14 |
| Congressional District 18 (115th Congress), Pennsylvania | Mike Doyle (D) | 704,815 | 0.141 | D+13 |
| Congressional District 5 (115th Congress), Pennsylvania | Mary Gay Scanlon (D) | 702,582 | 0.148 | D+13 |
| Congressional District 3 (115th Congress), Wisconsin | Ron Kind (D) | 718,086 | 0.150 | EVEN |
| Congressional District 7 (115th Congress), Wisconsin | Sean Duffy (R) | 707,988 | 0.153 | R+8 |
| Congressional District 8 (115th Congress), Minnesota | Pete Stauber (R) | 663,113 | 0.154 | R+4 |
| Congressional District 12 (115th Congress), Pennsylvania | VACANT (Marino) (R) | 699,504 | 0.155 | R+17 |
| Congressional District 27 (115th Congress), New York | Chris Collins (R) | 718,095 | 0.155 | R+11 |
| Congressional District 16 (115th Congress), Ohio | Anthony Gonzalez (R) | 722,933 | 0.156 | R+8 |
| Congressional District 4 (115th Congress), Michigan | John Moolenaar (R) | 700,749 | 0.159 | R+10 |
| Congressional District 1 (115th Congress), Tennessee | Phil Roe (R) | 712,059 | 0.159 | R+28 |
| Congressional District 6 (115th Congress), Indiana | Greg Pence (R) | 718,307 | 0.160 | R+18 |
| Congressional District 1 (115th Congress), New Hampshire | Chris Pappas (D) | 670,467 | 0.167 | R+2 |
| Congressional District 1 (115th Congress), Michigan | Jack Bergman (R) | 700,228 | 0.168 | R+9 |