Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
In this post, we piece together a brief political history of New Mexico using a host of data sources, including Wikipedia, the US Census, the New Mexico State Legislature (NMSL), VoteView, and the National Conference of State Legislatures. A bit of a show/tell post, and one that piggybacks some on a guide I have developed for working with US political data using R.
Here, we focus on the political leanings of voters in New Mexico as attested by who they have backed historically in presidential elections, who they have sent to the US Congress, and who they have elected as representation in the state legislature & governorship. As we will see, a curious history since statehood in 1912.
In the process, we demonstrate some methods for accessing/cleaning online data sets made available in a variety formats. Many of these data (especially those made available by the NMSL) have not really seen the light of day; so, we let these data breathe some. Fully reproducible. Open methods. Open government.
if (!require("pacman")) install.packages("pacman") pacman::p_load(tidyverse, tigris, nmelectiondatr) #devtools::install_github("jaytimm/nmelectiondatr") options(tigris_use_cache = TRUE, tigris_class = "sf")
New Mexico demographics via tidycensus
We first take a quick look at some socio-demographic indicators in New Mexico (relative to other states in the Union) using the tidycensus
package. The violin plots below summarize percentages of the population that are Hispanic (Per_Hispanic), White (Per_White), living below the poverty line (Per_BPL), have a Bachelor’s degree or higher (Per_Bachelors_Plus), and have a high school degree or higher (Per_HS_Plus). Also included are median household incomes (Median_HH_Income).
vars <- c(Per_Hispanic = 'DP05_0071P', Per_Bachelors_Plus = 'DP02_0067P', Per_BPL = 'DP03_0128P', Per_White = 'DP05_0077P', Per_HS_Plus = 'DP02_0066P', Median_HH_Income = 'DP03_0062') m90 <- tidycensus::get_acs(geography = "state", variables = vars, year = 2017, output = "tidy", survey = 'acs1') %>% filter(!GEOID %in% c('11', '72'))
So, New Mexico is browner, less financially heeled, and less educated relative to other states in the USA. A very simple overview of a fairly complicated state.
labs <- m90 %>% filter(NAME == 'New Mexico') m90 %>% ggplot(aes(x =1, y = estimate)) + geom_violin()+ geom_point() + ggrepel::geom_label_repel(data = labs, aes(x = 1, y = estimate, label = 'NM'), color = 'steelblue', nudge_x = .01)+ theme_minimal()+ theme(axis.title.x=element_blank(), axis.text.x=element_blank(), legend.position = "none") + facet_wrap(~variable, scales = 'free') + labs(title="Some socio-demographics", caption = 'American Community Survey, 1-Year Estimates, 2017.')
2016 Presidential Election
To get our bearings, we briefly consider how New Mexico voted in the 2016 presidential election. While Hillary Clinton carried the state by roughly eight points, here we investigate election results at the precinct level. My nmelectiondatr
package (available on GitHub) makes available election returns in New Mexico for state & federal elections from 2014 – 2018. These data live on the New Mexico Legislature website as fairly inaccessible spreadsheets. I have cleaned things up some, and collated returns as simple data tables. For non-R users, data also live as simple csv/excel files.
Here, we access precinct-level returns for the 2016 presidential election.
precincts_raw <- #nmelectiondatr::nmel_pol_geos$nm_precincts %>% nmelectiondatr::nmel_results_precinct %>% filter(Type == 'President and Vice President of the United States' ) %>% #& group_by(County_Name, Precinct_Num) %>% mutate(per = round(Votes/sum(Votes), 3)) %>% select(County_Name, Precinct_Num, Party, per) %>% filter(Party %in% c('DEM', 'REP')) %>% spread(Party, per) %>% mutate(Trump_Margin = REP - DEM) base <- nmelectiondatr::nmel_pol_geos$nm_precincts %>% inner_join(precincts_raw) %>% ggplot() + geom_sf(aes(fill = cut_width(Trump_Margin, 0.2)), color = 'darkgray') + scale_fill_brewer(palette = 'RdBu', direction = -1, name = 'Margin')
The map below summarizes Trump vote margins by precinct in New Mexico. So, an airplane-red state, much like the country as a whole, with larger, more rural precincts dominating the map.
base + ggsflabel::geom_sf_text_repel(data = nmel_pol_geos$nm_places %>% filter (LSAD == '25'), aes(label = NAME), size = 2.5) + theme_minimal() + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), legend.position = 'right') + labs(title = "2016 Trump margins by precinct")
When we zoom in some to New Mexico’s four largest metro areas, the state becomes a bit blue-er. Rio Rancho is the friendliest to 45 – where Trump held a rally in mid-September.
Presidential elections in New Mexico historically
A blue state in 2016, next we consider how New Mexico has voted in presidential elections since its statehood in 1912. We first grab a simple list of US presidents and their party affiliations via Git Hub.
url1 <- 'https://gist.githubusercontent.com/namuol/2657233/raw/74135b2637e624848c163759be9cd14ae33f5153/presidents.csv' us_pres <- read.csv(url(url1)) %>% #select(Year, Party) %>% mutate(Party = trimws(Party), Party = gsub('/.*$', '', Party), year = as.numeric(gsub('^.*/', '', Took.office))-1, President = gsub(' \\(.*$', '', President)) %>% select(year, President, Party) %>% mutate(Party = gsub('Democratic', 'Democrat', Party)) %>% bind_rows(data.frame(year = 2016, President = 'Donald Trump', Party = 'Republican'))
Then we access New Mexico’s presidential election voting history via Wikipedia.
url <- 'https://en.wikipedia.org/wiki/United_States_presidential_elections_in_New_Mexico' nm_returns <- url %>% xml2::read_html() %>% rvest::html_node(xpath = '//*[@id="mw-content-text"]/div/table[2]') %>% rvest::html_table(fill = TRUE) nm_returns <- nm_returns[,c(1:2, 4:5, 7)] colnames(nm_returns) <- c('year', 'winner', 'winner_per', 'loser', 'loser_per') nm_returns1 <- nm_returns %>% mutate(state_winner = ifelse(winner_per < loser_per, loser, winner))%>% rowwise() %>% mutate(other = round(100 - sum(winner_per, loser_per), 2)) %>% left_join(us_pres %>% select(-year), by = c('winner' = 'President')) wins <- nm_returns1 %>% select(year, state_winner, Party, winner_per)%>% rename(per = winner_per) loss <- nm_returns1 %>% select(year, state_winner, Party, loser_per)%>% mutate(Party = ifelse(Party == 'Democrat', 'Republican', 'Democrat')) %>% rename(per = loser_per) others <- nm_returns1 %>% select(year, state_winner, Party, other)%>% rename(per = other)%>% mutate(Party = 'Other') new <- bind_rows(wins, loss, others) new$Party <- factor(new$Party, levels = c('Other', 'Democrat', 'Republican'))
Based on these data, the plot below summarizes historical election results by party affiliation. Labeled are the candidates that won New Mexico. The gray portions of the plot reflect vote shares for “other”/ non-predominant political parties.
flip_dets <- c('Other', 'Democrat', 'Republican') flip_pal <- c('#b0bcc1', '#395f81', '#9e5055') names(flip_pal) <- flip_dets dems <- new %>% group_by(year) %>% filter(per == max(per)) %>% filter(Party == 'Democrat') pres_labels <- new %>% group_by(year) %>% filter(Party == 'Democrat') %>% mutate(percent1 = ifelse(state_winner %in% dems$state_winner, per + 7, per - 7), state_winner = toupper(sub('^.* ', '', state_winner))) new %>% ggplot(aes(x=year, y=per, fill = Party))+ geom_bar(alpha = 0.85, color = 'white', stat = 'identity') + annotate(geom="text", x = pres_labels$year, y = pres_labels$percent1, label = pres_labels$state_winner, size = 3, angle = 90, color = 'white')+ theme_minimal() + theme(axis.text.x = element_text(angle = 90, hjust = 1))+ #geom_hline(yintercept = 50, color = 'white', linetype = 2) + theme(legend.position = "none")+ #guides(fill = guide_legend(reverse=TRUE))+ scale_fill_manual(values = flip_pal) + #ggthemes::scale_fill_stata()+ scale_x_continuous(breaks=seq(1912,2016,4)) + xlab('') + ggtitle('Presidential election results in New Mexico')
Margins historically
For a slightly different perspective, we consider Republican-Democrat vote margins historically. As the plot below attests, a state that swings quite a bit. However, more recently having settled some as blue post-Bush v2.
new %>% select(-state_winner) %>% spread(Party, per) %>% mutate(margin = Republican - Democrat, Party = ifelse(margin > 0, 'Republican', 'Democrat')) %>% ggplot(aes(x=year, y=margin, fill = Party))+ geom_bar(alpha = 0.85, color = 'white', stat = 'identity') + theme_minimal() + theme(axis.text.x = element_text(angle = 90, hjust = 1))+ theme(legend.position = "none")+ ggthemes::scale_fill_stata()+ scale_x_continuous(breaks=seq(1912,2016,4)) + xlab('') + ggtitle('Presidential vote margins in New Mexico since 1912')
New Mexico as bellwether?
While New Mexico got Clinton wrong in 2016, the state seems a fairly consistent bellwether of presidential winners historically, supporting JKF, Ronald Reagan, and Barack Obama alike. Here, then, we consider how New Mexico stacks up against other states in the Union in terms of voting for the winning presidential candidate.
Below, we extract voting histories for all US states from Wikipedia. Tables are mostly uniform across states (eg, New Mexico). California & Pennsylvania tables, eg, are structured a bit differently, and require some individual tweaking.
base_url <- 'https://en.wikipedia.org/wiki/United_States_presidential_elections_in_' states <- uspoliticalextras::uspol_csusa_senate_bios %>% filter(congress == 116) %>% select(state_fips:state_abbrev)%>% distinct() %>% filter(!state %in% c('Pennsylvania', 'California'))%>% mutate(which_table = ifelse(state %in% c('New York', 'Missouri'), 3, 2)) states_correct <- list() for (i in 1:nrow(states)) { states_correct[[i]] <- paste0(base_url, states$state[i]) %>% xml2::read_html() %>% rvest::html_node(xpath = paste0('//*[@id="mw-content-text"]/div/table[', states$which_table[i],']')) %>% rvest::html_table(fill = TRUE) states_correct[[i]] <- states_correct[[i]][,c(1:2, 4:5, 7)] colnames(states_correct[[i]]) <- c('year', 'winner', 'winner_per', 'loser', 'loser_per') states_correct[[i]] <- states_correct[[i]] %>% mutate(winner_per = as.numeric(gsub('^$|-|%', 0, winner_per)), loser_per = as.numeric(gsub('^$|-|%', 0, loser_per)), state_winner = ifelse(winner_per < loser_per, loser, winner), correct = ifelse(state_winner == winner, 'correct', 'incorrect'), correct = ifelse(winner_per == 'n\a', NA, correct), year = as.integer(gsub("\\D+", "", year)), year = substr(year, 1,4))} names(states_correct) <- states$state states_correct1 <- states_correct %>% bind_rows(.id = 'state')
The table below summarizes how states have fared in predicting presidential election winners since 1912 – a total of 27 elections. New Mexico, then is tied for second with Missouri. Nevada and Ohio voters have only missed two winners since 1912.
correct <- states_correct1 %>% select(state, year, correct) %>% mutate(year = as.integer(year)) %>% bind_rows(returns1, returns_ca) %>% filter(year > 1911) %>% group_by(state, correct) %>% summarize(n = n()) %>% filter(!is.na(correct))%>% spread(correct, n) %>% ungroup() %>% rowwise() %>% mutate(per_correct = round(correct/sum(correct, incorrect), 3)) correct %>% arrange(desc(per_correct))%>% DT::datatable(rownames = FALSE) %>% DT::formatStyle('per_correct', background = DT::styleColorBar(range(correct[4]), 'lightblue'), backgroundSize = '80% 70%', backgroundRepeat = 'no-repeat', backgroundPosition = 'right')
Elections New Mexico got wrong
The table below summarizes results for elections that New Mexico, Ohio, Missouri, and Nevada got wrong since 1912. So, Ohio has been on spot since 1960; Missouri has (seemingly) gone full red. Also of note: 2/3 presidential nominees that New Mexico got wrong won the popular vote nationally, ie, Al Gore & HR Clinton.
states_correct1 %>% filter(state %in% c('Ohio', 'Nevada', 'New Mexico', 'Missouri') & correct == 'incorrect' & year > 1911) %>% select(state:loser_per) %>% knitr::kable()
state | year | winner | winner_per | loser | loser_per |
---|---|---|---|---|---|
Missouri | 2012 | Barack Obama | 44.38 | Mitt Romney | 53.76 |
Missouri | 2008 | Barack Obama | 49.29 | John McCain | 49.43 |
Missouri | 1956 | Dwight D. Eisenhower | 49.89 | Adlai Stevenson II | 50.11 |
Nevada | 2016 | Donald Trump | 45.50 | Hillary Clinton | 47.92 |
Nevada | 1976 | Jimmy Carter | 45.81 | Gerald Ford | 50.17 |
New Mexico | 2016 | Donald Trump | 40.04 | Hillary Clinton | 48.26 |
New Mexico | 2000 | George W. Bush | 47.85 | Al Gore | 47.91 |
New Mexico | 1976 | Jimmy Carter | 48.28 | Gerald Ford | 50.75 |
Ohio | 1960 | John F. Kennedy (D) | 46.72 | Richard Nixon (R) | 53.28 |
Ohio | 1944 | Franklin D. Roosevelt (D) | 49.82 | Thomas E. Dewey (R) | 50.18 |
The map below illustrates state ranks for voting with the presidential winner since 1912 (based on table above). States in darker blue are better bellwethers. So, the Southwest is generally quite good, while the South & New England less so.
correct_labels <- correct %>% ungroup() %>% arrange(desc(correct)) %>% mutate(rank = dplyr::dense_rank(desc(correct))) out <- uspoliticalextras::uspol_dvos_equalarea_sf$tile_outer %>% left_join(correct_labels) inner <- uspoliticalextras::uspol_dvos_equalarea_sf$tile_inner %>% left_join(correct_labels) %>% mutate(rank_label = paste0(state_abbrev, '\n', rank)) out %>% ggplot() + geom_sf(aes(fill = rank), color = 'black') + ggsflabel::geom_sf_text(data = inner, aes(label = rank_label), size = 3.5, color = 'black') + theme_minimal() + scale_fill_gradient(low="#2c7bb6", high="#ffffbf")+ theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), legend.title=element_blank(), legend.position = 'none') + labs(title = "Voting with winning candidate since 1912 by rank")
Congressional delegation historically
Next, we consider the composition of New Mexico’s congressional delegation historically. Here we access data made available via the VoteView project and the R package Rvoteview
.
House of Representatives
The table below details the names & party affiliations of the (3) representatives New Mexico has sent to Washington over the last 15 congresses. District 3, which is comprised of the northern half of the state and includes the Santa Fe metro, has generally gone blue during this time period. District 1 (the ABQ metro area) has flipped from red to blue since the election of Obama in 2008. District 2 (the southern half of the sate) has been a GOP stronghold, with the 111th and 116th congresses being exceptions.
js <- "(/Rep/).test(value) ? '#fcdbc7' : (/Dem/).test(value) ? '#d1e6ef' : ''" dat <- Rvoteview:: member_search(chamber= 'House', state = 'NM', congress = 102:116) %>% mutate(bioname = gsub('\\(Tom\\)', '', bioname), bioname = ifelse(party_name == 'Democratic Party', paste0(bioname, ' (Dem)'), paste0(bioname, ' (Rep)'))) %>% select(congress, bioname, district_code) %>% group_by(congress, district_code)%>% slice(1) %>% ungroup() %>% spread(district_code, bioname) dat %>% DT::datatable(rownames = FALSE, options = list(pageLength = 15, dom = 't')) %>% DT::formatStyle(1:ncol(dat), backgroundColor = htmlwidgets::JS(js))
So, 2018 (the 116th) was only the second time in the last thirty years that New Mexico elected an all-Democrat delegation to the House. See this post for some thoughts on how Torres Small carried New Mexico’s second district in 2018.
US Senate
Next we consider the political affiliations & ideologies of US Senators from New Mexico since 1947. I have discussed VoteView’s political ideology scores in previous posts (eg), and have also demonstrated their derivation using roll call data from New Mexico’s 53rd State Legislature as an example.
Here we utilize Nokken-Poole
political ideology scores, which are congress-specific scores. These data are not available via the Rvoteview
package; instead, we download these scores directly from the VoteView website.
voteview_nokken_poole <- read.csv(url("https://voteview.com/static/data/out/members/HSall_members.csv"), stringsAsFactors = FALSE) base1 <- voteview_nokken_poole %>% filter(!is.na(nokken_poole_dim1), chamber == 'Senate', party_code %in% c('100','200')& congress > 79) nm <- base1 %>% filter(state_abbrev == 'NM') nm_labels <- nm %>% group_by(bioname) %>% filter(congress == max(congress)) %>% ungroup() %>% mutate(bioname = gsub(',.*$', '', bioname))
Below, the names and political ideology scores (first dimension) of Senators from New Mexico are presented relative to the median ideology for each major party historically. So, a history of fairly moderate representation in the Senate – dominated until more recently by the split delegation of Domenici (R) and Bingaman (D), both of whom voted center of their respective party medians. Udall (D) and Heinrich (D) may be drifting left, but this would reflect the state’s shifting ideology in general.
base2 <- base1 %>% group_by(congress, party_code) %>% summarize(med = median(nokken_poole_dim1)) %>% ungroup() %>% ggplot() + geom_line(aes(x = congress, y= med, color = as.factor(party_code)), size = 1.25) + ylim(-.5, .5) + theme_minimal()+ ggthemes::scale_color_stata() + theme(legend.position = 'none') + labs(title="Median ideologies for major parties: Houses 80 to 116") base2 + geom_line(data = nm, aes(x = congress, y= nokken_poole_dim1, color = as.factor(bioname)), linetype = 2) + geom_text(data = nm_labels, aes(label = bioname, x = congress, y =nokken_poole_dim1), size = 3)
New Mexico State Government
Finally, we consider the composition of New Mexico’s state government historically, namely the governorship and the bicameral house.
State Control in 2019
For a quick look at the current & aggregate composition of New Mexican state leadership relative to other US states, we access data made available by the National Conference of State Legislatures (NCSL).
x <- 'http://www.ncsl.org/Portals/1/Documents/Elections/Legis_Control_2019_August%2026th.pdf' tmp <- tempfile() curl::curl_download(x, tmp) tab <- tabulizer::extract_tables(tmp, output = "data.frame", encoding = 'UTF-8')[[1]] %>% slice(2:51) %>% select(1,4:5, 7:8, 11:13) %>% separate(col = `Total.House`, into = c('total_house', 'dem'), sep = ' ') %>% select(-total_house) %>% filter(X != 'Nebraska') colnames(tab) <- c('state', 'sen_dem', 'sen_rep', 'house_dem', 'house_rep', 'legis_control', 'governor', 'state_control') tab$state_control <- factor(tab$state_control, levels = c('Divided', 'Dem', 'Rep'))
The table below presents a sample of the NCSL data set, which includes composition of bicameral state houses by party affiliation, as well as the political affiliation of current governors. The legis_control
variable indicates whether the House & Senate are controlled by the same party or not. Eg, both houses in California are controlled by Democrats, while in Minnesota, Republicans control the House and Democrats the Senate, ie, the houses are divided. The state_control
variable indicates whether both houses and the governorship are controlled by the same party or not.
set.seed(89) tab %>% sample_n(5) %>% knitr::kable() %>% kableExtra::kable_styling("striped")
state | sen_dem | sen_rep | house_dem | house_rep | legis_control | governor | state_control |
---|---|---|---|---|---|---|---|
California | 29 | 11 | 61 | 18 | Dem | Dem | Dem |
Minnesota | 32 | 35 | 75 | 59 | Divided | Dem | Divided |
New York | 40 | 22 | 106 | 43 | Dem | Dem | Dem |
Connecticut | 22 | 14 | 91 | 60 | Dem | Dem | Dem |
Iowa | 18 | 32 | 46 | 53 | Rep | Rep | Rep |
As far as state legislatures go, very little division exists nationally. The table below summarizes the distribution of legislature control-types (Republican, Democrat, or divided) for the 49 states in the Union with bicameral state houses. Only Minnesota has a divided legislature.
Dem | Divided | Rep |
---|---|---|
18 | 1 | 30 |
State control is a bit more divided nationally, with thirteen states having divided gubernatorial and legislative party control. Thirty-six have state government trifectas.
Divided | Dem | Rep |
---|---|---|
13 | 14 | 22 |
The map below illustrates government control by state and party affiliation for 2019. New Mexico, then, is one of fourteen states with a Democratic state government trifecta. This is new – during the previous eight years (at least) state control was divided in New Mexico.
flip_dets <- c('Divided', 'Dem', 'Rep') flip_pal <- c('gray', '#395f81', '#9e5055') names(flip_pal) <- flip_dets uspoliticalextras::uspol_dvos_equalarea_sf$tile_outer %>% left_join(tab) %>% ggplot() + geom_sf(aes(fill = state_control), color = 'black', alpha = .75) + ggsflabel::geom_sf_text(data = uspoliticalextras::uspol_dvos_equalarea_sf$tile_inner, aes(label = state_abbrev), size = 3.5, color = 'white') + theme_minimal()+ scale_fill_manual(values = flip_pal) + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.title.y=element_blank(), axis.text.y=element_blank(), legend.title=element_blank(), legend.position = 'bottom') + labs(title = "State government control in 2019")
Governors historically
Next, we investigate the party affiliation of New Mexico’s governors since its statehood in 1912. These data are made available as a PDF from the New Mexico State Legislature website.
url <- 'https://www.nmlegis.gov/Publications/Handbook/leadership_since_statehood_17.pdf' tmp <- tempfile() curl::curl_download(url, tmp) tab <- tabulizer::extract_tables(tmp, output = "data.frame") xx <- c('year', 'speaker', 'pro_tem', 'governor', 'president') tab1 <- lapply(tab, function(x) { colnames(x) <- xx return(x) }) %>% bind_rows() %>% mutate(governor = gsub('\\(died\\)|\\(resigned\\)', NA, governor), president = gsub('\\(died\\)|\\(resigned\\)', NA, president), president = gsub('^$', NA, president)) %>% tidyr::fill(governor, .direction = 'up') %>% tidyr::fill(president, .direction = 'up') %>% filter(!is.na(year)) %>% mutate(gov_party = gsub('^.*\\(([A-Z])\\)', '\\1', governor), pres_party = gsub('^.*\\(([A-Z])\\)', '\\1', president), governor = gsub('\\(.\\)', '', governor), president = gsub('\\(.\\)', '', president)) %>% select(-speaker, -pro_tem) #Tabulizer is not perfect. PDF is not up-to-date. hand_edits <- data.frame (year = c(1912, 1951:1953, 2000, 2018:2019), governor = c('McDonald', 'Horn', 'Horn', 'Stockton', 'Sanchez', 'Martinez', 'Lujan Grisham'), president = c('Wilson', 'Truman', 'Truman', 'Eisenhower', 'Clinton', 'Trump, D.', 'Trump, D.'), gov_party = c('D', 'D', 'D', 'R', 'D', 'R', 'D'), pres_party = c('D', 'D', 'D', 'R', 'D', 'R', 'R')) tab1 <- tab1 %>% bind_rows(hand_edits) %>% arrange(year)
After some cleaning, a sample of our data set is presented below. Included are the names of sitting US Presidents and their political affiliation.
year | governor | president | gov_party | pres_party |
---|---|---|---|---|
1912 | McDonald | Wilson | D | D |
1913 | McDonald | Wilson | D | D |
1914 | McDonald | Wilson | D | D |
1915 | McDonald | Wilson | D | D |
1916 | McDonald | Wilson | D | D |
1917 | C de Baca | Wilson | D | D |
The table below summarizes the total number of years (since 1912) that each party has held the governor’s office, cross-tabbed with the political affiliation of the US President during the same time period. First to note is that Democrats have held gubernatorial control in 70/108 years.
Second to note is that in 59 (39 + 20) of those years the New Mexico governor shared party affiliation with the sitting US President; in 49 (18 + 31) of those years, the two were divided. Roughly a 50-50 split historically, which is pretty interesting.
table(tab1$gov_party, tab1$pres_party) %>% data.frame() %>% rename(Gov_Party = Var1, Pres_Party = Var2) %>% spread(Pres_Party, Freq) %>% knitr::kable()%>% kableExtra::kable_styling("striped", full_width = F) %>% kableExtra::add_header_above(c(" " = 1, "Pres_Party" = 2))
Pres_Party
|
||
---|---|---|
Gov_Party | D | R |
D | 39 | 31 |
R | 18 | 20 |
In rank order by total years, then:
- [Dem Gov/Dem Pres (39)] > [Dem Gov/Rep Pres (31)] > [Rep Gov/Rep Pres (20)] > [Rep Gov/Dem Pres (18)]
The plot below illustrates the political affiliation of New Mexico governors and US presidents since statehood in 1912. Lots of back and forth for sure. It would seem that New Mexicans hedge their bets when it comes to gubernatorial elections, tempering federal leadership with state leadership from the opposing party. With the exception of the ~FDR years.
tab1 %>% mutate(gov_val = ifelse(gov_party == 'D', .75, -.75), pres_val = ifelse(pres_party == 'D', 1, -1)) %>% ggplot() + geom_line(aes(x = year, y = gov_val), size = 1.25, color = '#b0bcc1') + geom_line(aes(x = year, y = pres_val), size = 1.25, color = '#55752f') + ylim(-1.25, 1.25) + theme_minimal()+ annotate("text", x = 1920, y = 1.25, label = "DEMOCRAT") + annotate("text", x = 1920, y = -1.25, label = "REPUBLICAN") + annotate("text", x = 1914, y = 1.05, label = "President") + annotate("text", x = 1914, y = .8, label = "Governor") + theme(legend.position = 'none', axis.title.y=element_blank(), axis.text.y=element_blank(), axis.text.x = element_text(angle = 90, hjust = 1)) + scale_x_continuous(breaks=seq(1912,2018,4)) + labs(title="Presidential & Gubernatorial Party Affiliation by Year")
State legislature composition historically
LASTLY, we investigate the party-based composition of the New Mexico state houses historically. Again, we access this data via a PDF made available at the New Mexico State Legislature website.
url_state <- 'https://www.nmlegis.gov/Publications/Handbook/political_control_17.pdf' tmp <- tempfile() curl::curl_download(url_state, tmp) tab <- tabulizer::extract_tables(tmp, output = "data.frame", encoding = 'UTF-8') current <- data.frame(year = c(2019, 2019), count = c(26,16, 46, 24), house = c('senate', 'senate', 'house', 'house'), party = c('dem', 'rep', 'dem', 'rep')) xx <- c('year', 'house', 'house_dem', 'house_rep', 'house_other', 'senate_dem', 'senate_rep', 'senate_other') tab2 <- lapply(tab, function(x) { x <- x[, c(1:4,6, 8:9, 11)] colnames(x) <- xx x$house_other <- as.numeric(x$house_other) x$senate_other <- as.numeric(x$senate_other) return(x) }) %>% bind_rows() %>% filter(year %% 2 == 1 | house == '31st,2nd') %>% filter(!grepl('SS', house)) %>% mutate(house = gsub(',.*$', '', house)) %>% gather(key = 'type', value = 'count', -year, -house) %>% separate(type, into = c('house', 'party'), sep = '_') %>% mutate(count = ifelse(is.na(count), 0, count)) %>% bind_rows(current) %>% group_by(year, house) %>% mutate(per = round(count/sum(count),2)) %>% ungroup() tab2$party <- factor(tab2$party, levels = c('other', 'dem', 'rep'))
Per plot below, then, a post-Depression era stronghold for Democrats, with a couple of exceptions – most recently in the 52nd House (which took office in 2015). A bit of a different story relative to the state’s swingy-er tendancies in other offices considered here.
flip_dets <- c('other', 'dem', 'rep') flip_pal <- c('#b0bcc1', '#395f81', '#9e5055') names(flip_pal) <- flip_dets tab2 %>% ggplot(aes(x=year, y=per, fill = party))+ geom_area(alpha = 0.85, color = 'white', stat = 'identity') + geom_hline(yintercept = .50, color = 'white', linetype = 2) + theme_minimal() + theme(axis.text.x = element_text(angle = 90, hjust = 1))+ theme(legend.position = "none")+ scale_fill_manual(values = flip_pal) + scale_x_continuous(breaks=seq(1913, 2019, 8)) + xlab('') + ggtitle('Composition of New Mexico state houses since statehood') + facet_wrap(~house)
Summary
At present, then, New Mexico is a blue state. While Trump rallied in Rio Rancho in September in hopes of capturing the state in 2020, New Mexico has (seemed to have) lost some of the SWING that has defined the state through much of its history. And made it an excellent bellwether for presidential election winners.
The state supported Clinton in 2016, sends two Democrats to the Senate, 3/3 Democrats to the House, and has a Democratic state government trifecta. These things are fluid for sure, but the state’s demographics continue to move the state’s political ideology leftwards. So, we’ll see. Open data. Open government.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.