front-line house democrats: a quick guide

So, with an impeachment vote nigh and the 2020 general elections slowly approaching, lots of talk about the 31 House Democrats that represent congressional districts won by the sitting president in 2016 (here, front-line House Democrats). In this post, we present a quick/simple/R-based investigation into the composition of this group of Democrats from several different perspectives. We also consider the 43 congressional districts that flipped Democratic in the 2018 midterms.

Pundits constantly cite these districts and count them in different ways; and I am constantly trying to recreate these counts. As open source federal election data can be a bit of a mess, this is an attempt to organize & collate some data sources.

House & presidential election returns

The R data package uspoliticalextras includes federal election returns from a couple of sources, namely the Daily Kos and the MIT Election Data and Science Lab. I use the package as a bit of a cache for US political data; it is available via Git Hub. The focus here will be on the last Presidential election (2016) & the last two House races (2016 & 2018).

library(tidyverse)
#devtools::install_github("jaytimm/uspoliticalextras")  
pres <- uspoliticalextras::uspol_dkos_returns_pres_cd 
house <- uspoliticalextras::uspol_medsl_returns_house_cd %>%
  filter(year > 2015) %>%
  mutate(party = ifelse(party == 'Independent', 'Republican Party', party)) # Amash

2016 Presidential vote margins

Number of congressional districts carried by DJT & HRC.

pres %>%
  filter(year == 2016) %>%
  group_by(candidate) %>%
  count() %>%
  knitr::kable()
candidate n
Clinton 205
Trump 230

Trump margins by congressional district in 2016.

library(sf)
to_map <- uspoliticalextras::uspol_dkos_equalarea_sf$hex_cds %>%
  select(GEOID) %>%
  left_join(pres %>% 
              filter(year == 2016) %>% 
              mutate(trump_margin = republican - democrat),
            by = 'GEOID') 
to_map %>%
  ggplot() + 
  geom_sf(aes(fill = trump_margin),
          color = 'white') +
  geom_sf(data=uspoliticalextras::uspol_dkos_equalarea_sf$hex_states, 
          fill = NA, 
          show.legend = F, 
          color="#5a5c5b", 
          lwd=.5) +
  ggsflabel::geom_sf_text(data = uspoliticalextras::uspol_dkos_equalarea_sf$hex_cds,
                          aes(label = district_code), 
                          size = 2,
                          color='black') +
  scale_fill_distiller(palette = "RdBu", direction=-1) +
  theme_minimal()+
  theme(axis.text.x=element_blank(),
        axis.text.y=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        legend.position = 'none') +
  labs(title = "2016 Trump Margins by Congressional District",
       caption = 'Source: Daily Kos')

Flipped House Districts: 2016 to 2018

Congressional districts that elected a Republican representative in 2016 and a Democratic representative in 2018.

house_flips <- house %>%
  select(GEOID, congress,party) %>%
  spread(congress, party) %>%
  left_join(house %>% 
              filter(year == 2018) %>% 
              mutate(house_rep_margin = round(republican - democrat, 1)) %>%
              select(GEOID, state_abbrev, district_code, candidate, house_rep_margin) %>% 
              rename(house_rep = candidate))

Some corrections/amendments for Pennsylvania districts per 2019 redistricting.

pa16_rs <- c('4201', '4205', '4206',
           '4207', '4209', '4210',
           '4211', '4212', '4213','4215',
           '4216', '4217')
pa16_ds <- c('4202', '4203', '4204',
           '4208',  '4214',
           '4218')
pa18_rs <- c('4203', '4204', '4205', '4218')
pa18_ds <- c('4213', '4214')
house_flips1 <-  house_flips %>%
  mutate(`115` = ifelse(GEOID %in% pa16_rs, 'Republican Party', `115`),
         `115` = ifelse(GEOID %in% pa16_ds, 'Democratic Party', `115`)) %>%
  mutate(house_flip = paste0(`115`, ' | ', `116`)) %>%
  left_join(to_map %>% 
              sf::st_drop_geometry() %>% 
              select(GEOID, candidate, trump_margin)) %>%
  rename(Pres16 = candidate) %>%
  mutate(`116` = ifelse(GEOID %in% pa18_rs, 'Republican Party', `116`),
         `116` = ifelse(GEOID %in% pa18_ds, 'Democratic Party', `116`)) %>%  
  mutate(Pres16_House18 = paste0(Pres16, ' | ', `116`))

Democrats netted a total of 40 seats in the midterm elections in 2018. The numbers & districts presented below align with those presented on Bollotpedia.

house_flips1 %>%
  group_by(house_flip) %>%
  count() %>%
  knitr::kable()
house_flip n
Democratic Party | Democratic Party 192
Democratic Party | Republican Party 3
Republican Party | Democratic Party 42
Republican Party | Republican Party 198

House Representatives from flipped districts:

house_flips1 %>%
  filter(house_flip %in% 
           c('Democratic Party | Republican Party', 
             'Republican Party | Democratic Party')) %>%
  mutate(house_flip = ifelse(grepl('^D', house_flip), 'D -> R', 'R -> D')) %>%
  select(house_flip, state_abbrev, district_code, house_rep) %>%
  DT::datatable(rownames = FALSE)

The 31 front-line House Democrats

The table below summarizes how districts voted in the 2016 presidential election and House elections in 2018. Again, 31 House Democrats represent congressional districts that Trump won in 2016’s presidential election. In contrast, only three Republicans represent districts carried by HRC. Note: Numbers & districts align with those presented in this article from The Hill.

house_flips1 %>%
  group_by(Pres16_House18) %>%
  count() %>%
  #mutate(n = formattable::color_tile('white', 'steelblue')(n)) %>%
  knitr::kable()
Pres16_House18 n
Clinton | Democratic Party 202
Clinton | Republican Party 3
Trump | Democratic Party 30
Trump | Republican Party 200

The 31 Democratic lawmakers representing Trump-won districts include:

house_flips1 %>%
  filter(Pres16_House18 == 'Trump | Democratic Party') %>%
  select(state_abbrev, district_code, house_rep) %>%
  DT::datatable(rownames = FALSE)

A quick geographical perspective of the front-line

to_map2 <- uspoliticalextras::uspol_dkos_equalarea_sf$hex_cds %>%
  select(GEOID) %>%
  left_join(house_flips1, by = 'GEOID') 

to_map2 %>%
  ggplot() + 
  geom_sf(aes(fill = Pres16_House18),
          alpha = .75,
          color = 'white') +
  geom_sf(data=uspoliticalextras::uspol_dkos_equalarea_sf$hex_states, 
          fill = NA, 
          show.legend = F, 
          color="black", 
          lwd=.5) +
  ggsflabel::geom_sf_text(data = uspoliticalextras::uspol_dkos_equalarea_sf$hex_cds,
                          aes(label = district_code), 
                          size = 2,
                          color='black') +
  ggthemes::scale_fill_stata() +
  theme_minimal()+
  theme(axis.text.x=element_blank(),
        axis.text.y=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        legend.position = 'bottom') +
  labs(title = "2016 Presidential Support & 2018 House Representative",
       subtitle = 'By Congressional District')

The 13 House Democrats in solid Trump districts

Of the 31 front-liners, thirteen represent districts Trump carried by more than 6 points.

house_flips1 %>%
  filter(Pres16_House18 == 'Trump | Democratic Party' & trump_margin > 6) %>%
  select(state_abbrev, district_code, house_rep, trump_margin) %>%
  arrange(desc(trump_margin)) %>%
  knitr::kable()
state_abbrev district_code house_rep trump_margin
MN 7 PETERSON, Collin Clark 30.8
NY 22 BRINDISI, Anthony 15.5
OK 5 HORN, Kendra 13.4
SC 1 CUNNINGHAM, Joe 13.1
ME 2 GOLDEN, Jared 10.3
NM 2 TORRES SMALL, Xochitl 10.2
PA 17 LAMB, Conor 10.1
NY 11 ROSE, Max 9.8
NY 19 DELGADO, Antonio 6.8
MI 8 SLOTKIN, Elissa 6.7
UT 4 McADAMS, Ben 6.7
VA 7 SPANBERGER, Abigail 6.5
NJ 3 KIM, Andy 6.2

Voting patterns in presidential elections by district

Counts of how districts voted in the last three presidential elections are presented below.

house_flips2 <- house_flips1 %>%
  left_join (pres %>% 
               group_by(GEOID) %>%
               summarize(pres_lineage = paste0(candidate, collapse = ' | ')) %>%
               ungroup())
house_flips2 %>%
  group_by(pres_lineage) %>%
  count() %>%
  knitr::kable()
pres_lineage n
McCain | Obama | Trump 1
McCain | Romney | Clinton 8
McCain | Romney | Trump 184
Obama | Obama | Clinton 190
Obama | Obama | Trump 20
Obama | Romney | Clinton 7
Obama | Romney | Trump 25

Voting patterns in presidential elections for front-line districts

12 out of the 31 front-line districts have voted for Republican presidential candidates in the last three elections, ie, McCain-Romney-Trump districts.

house_flips2 %>%
  filter(Pres16_House18 == 'Trump | Democratic Party') %>%
  group_by(pres_lineage) %>%
  count() %>%
  knitr::kable()
pres_lineage n
McCain | Obama | Trump 1
McCain | Romney | Trump 12
Obama | Obama | Trump 13
Obama | Romney | Trump 4

Representatives for these twelve districts are presented below.

house_flips2 %>%
  filter(Pres16_House18 == 'Trump | Democratic Party' & 
           pres_lineage == 'McCain | Romney | Trump') %>%
  select(state_abbrev, district_code, house_rep) %>%
  knitr::kable()
state_abbrev district_code house_rep
AZ 1 O’HALLERAN, Thomas C.
GA 6 McBATH, Lucy
MN 7 PETERSON, Collin Clark
NJ 5 GOTTHEIMER, Josh S.
NJ 11 SHERRILL, Mikie
NM 2 TORRES SMALL, Xochitl
NY 22 BRINDISI, Anthony
OK 5 HORN, Kendra
SC 1 CUNNINGHAM, Joe
UT 4 McADAMS, Ben
VA 2 LURIA, Elaine
VA 7 SPANBERGER, Abigail

The 5 House Democrats that should probably vote against impeachment

The table below lists the five House Reps representing districts that have supported Republican presidential candidates in the last three elections, with 2016 Trump margins greater than ten points.

house_flips2 %>%
  filter(Pres16_House18 == 'Trump | Democratic Party' & 
           trump_margin > 10 &
           pres_lineage == 'McCain | Romney | Trump') %>%
  select(state_abbrev, district_code, house_rep, pres_lineage, trump_margin) %>%
  arrange(desc(trump_margin)) %>%
  knitr::kable()
state_abbrev district_code house_rep pres_lineage trump_margin
MN 7 PETERSON, Collin Clark McCain | Romney | Trump 30.8
NY 22 BRINDISI, Anthony McCain | Romney | Trump 15.5
OK 5 HORN, Kendra McCain | Romney | Trump 13.4
SC 1 CUNNINGHAM, Joe McCain | Romney | Trump 13.1
NM 2 TORRES SMALL, Xochitl McCain | Romney | Trump 10.2

Freshmen House Representatives

Via the Rvoteview package, we identify 88 freshman House Representatives, 56 of which are Democrats.

house_vv_freshies <- Rvoteview:: member_search(chamber= 'House', congress = 116) %>%
  filter(congresses == 'c(116, 116)' & party_name != 'Independent') %>%
  select(bioname, party_name) %>%
  rename(house_rep = bioname) 

house_vv_freshies %>%
  group_by(party_name) %>%
  count() %>%
  knitr::kable()
party_name n
Democratic Party 56
Republican Party 33

Of the 31 front-liners, then, 22 are freshman. So, a pretty vulnerable group.

house_flips3 <- house_flips2 %>%
  left_join(house_vv_freshies %>% 
              mutate(is_fresh = 'Y') %>% 
              select(house_rep, is_fresh)) %>%
  mutate(is_fresh = ifelse(is.na(is_fresh), 'N', is_fresh))

house_flips3 %>%
  group_by(is_fresh, Pres16_House18) %>%
  count() %>%
  #filter(is_fresh == 'Y') %>%
  spread(is_fresh, n) %>%
  janitor::adorn_totals(where = c('row', 'col')) %>%
  knitr::kable()
Pres16_House18 N Y Total
Clinton | Democratic Party 167 35 202
Clinton | Republican Party 3 NA 3
Trump | Democratic Party 9 21 30
Trump | Republican Party 170 31 201
Total 349 87 436

Data set

The data set compiled in this post/guide is available here.

Share