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.
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_detsdems <- 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$statestates_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')
{"x":{"filter":"none","data":[["Nevada","Ohio","Missouri","New Mexico","Florida","Tennessee","Illinois","Kentucky","Montana","Arizona","California","Colorado","Delaware","Idaho","Maryland","New Hampshire","New Jersey","Utah","Wisconsin","Arkansas","Iowa","New York","North Carolina","Oklahoma","Pennsylvania","Texas","Virginia","West Virginia","Wyoming","Connecticut","Louisiana","Massachusetts","Michigan","Oregon","Rhode Island","Washington","Indiana","Kansas","Minnesota","Nebraska","North Dakota","Georgia","South Carolina","Alaska","Hawaii","Mississippi","South Dakota","Alabama","Maine","Vermont"],[25,25,24,24,23,23,22,22,22,21,21,21,21,21,21,21,21,21,21,20,20,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,18,18,18,18,18,17,17,9,9,16,16,15,15,15],[2,2,3,3,4,4,5,5,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,10,10,6,6,11,11,12,12,12],[0.926,0.926,0.889,0.889,0.852,0.852,0.815,0.815,0.815,0.778,0.778,0.778,0.778,0.778,0.778,0.778,0.778,0.778,0.778,0.741,0.741,0.741,0.741,0.741,0.741,0.741,0.741,0.741,0.741,0.704,0.704,0.704,0.704,0.704,0.704,0.704,0.667,0.667,0.667,0.667,0.667,0.63,0.63,0.6,0.6,0.593,0.593,0.556,0.556,0.556]],"container":"</p><table class=\"display\">\n </p><thead>\n </p><tr>\n </p><th>state<\/th>\n </p><th>correct<\/th>\n </p><th>incorrect<\/th>\n </p><th>per_correct<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"columnDefs":[{"className":"dt-right","targets":[1,2,3]}],"order":[],"autoWidth":false,"orderClasses":false,"rowCallback":"function(row, data) {\nvar value=data[3]; $(this.api().cell(row, 3).node()).css({'background':isNaN(parseFloat(value)) || value <= 0.556000 ? '' : 'linear-gradient(90.000000deg, transparent ' + (0.926000 - value)/0.370000 * 100 + '%, lightblue ' + (0.926000 - value)/0.370000 * 100 + '%)','background-size':'80% 70%','background-repeat':'no-repeat','background-position':'right'});\n}"}},"evals":["options.rowCallback"],"jsHooks":[]}
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))
{"x":{"filter":"none","data":[[102,103,104,105,106,107,108,109,110,111,112,113,114,115,116],["SCHIFF, Steven Harvey (Rep)","SCHIFF, Steven Harvey (Rep)","SCHIFF, Steven Harvey (Rep)","SCHIFF, Steven Harvey (Rep)","WILSON, Heather (Rep)","WILSON, Heather (Rep)","WILSON, Heather (Rep)","WILSON, Heather (Rep)","WILSON, Heather (Rep)","HEINRICH, Martin (Dem)","HEINRICH, Martin (Dem)","LUJAN GRISHAM, Michelle (Dem)","LUJAN GRISHAM, Michelle (Dem)","LUJAN GRISHAM, Michelle (Dem)","HAALAND, Debra (Dem)"],["SKEEN, Joseph Richard (Rep)","SKEEN, Joseph Richard (Rep)","SKEEN, Joseph Richard (Rep)","SKEEN, Joseph Richard (Rep)","SKEEN, Joseph Richard (Rep)","SKEEN, Joseph Richard (Rep)","PEARCE, Stevan (Rep)","PEARCE, Stevan (Rep)","PEARCE, Stevan (Rep)","TEAGUE, Harry (Dem)","PEARCE, Stevan (Rep)","PEARCE, Stevan (Rep)","PEARCE, Stevan (Rep)","PEARCE, Stevan (Rep)","TORRES SMALL, Xochitl (Dem)"],["RICHARDSON, Bill (Dem)","RICHARDSON, Bill (Dem)","RICHARDSON, Bill (Dem)","REDMOND, William Thomas (Rep)","UDALL, Thomas (Dem)","UDALL, Thomas (Dem)","UDALL, Thomas (Dem)","UDALL, Thomas (Dem)","UDALL, Thomas (Dem)","LUJÁN, Ben Ray (Dem)","LUJÁN, Ben Ray (Dem)","LUJÁN, Ben Ray (Dem)","LUJÁN, Ben Ray (Dem)","LUJÁN, Ben Ray (Dem)","LUJÁN, Ben Ray (Dem)"]],"container":"</p><table class=\"display\">\n </p><thead>\n </p><tr>\n </p><th>congress<\/th>\n </p><th>1<\/th>\n </p><th>2<\/th>\n </p><th>3<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"pageLength":15,"dom":"t","columnDefs":[{"className":"dt-right","targets":0}],"order":[],"autoWidth":false,"orderClasses":false,"lengthMenu":[10,15,25,50,100],"rowCallback":"function(row, data) {\nvar value=data[0]; $(this.api().cell(row, 0).node()).css({'background-color':(/Rep/).test(value) ? '#fcdbc7' : (/Dem/).test(value) ? '#d1e6ef' : ''});\nvar value=data[1]; $(this.api().cell(row, 1).node()).css({'background-color':(/Rep/).test(value) ? '#fcdbc7' : (/Dem/).test(value) ? '#d1e6ef' : ''});\nvar value=data[2]; $(this.api().cell(row, 2).node()).css({'background-color':(/Rep/).test(value) ? '#fcdbc7' : (/Dem/).test(value) ? '#d1e6ef' : ''});\nvar value=data[3]; $(this.api().cell(row, 3).node()).css({'background-color':(/Rep/).test(value) ? '#fcdbc7' : (/Dem/).test(value) ? '#d1e6ef' : ''});\n}"}},"evals":["options.rowCallback"],"jsHooks":[]}
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.
State control is a bit more divided nationally, with thirteen states having divided gubernatorial and legislative party control. Thirty-six have state government trifectas.
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_detsuspoliticalextras::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_detstab2 %>% 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)
![]()
var vglnk = { key: '949efb41171ac6ec1bf7f206d57e90b8' }; (function(d, t) {var s = d.createElement(t); s.type = 'text/javascript'; s.async = true;s.src = '//cdn.viglink.com/api/vglnk.js';var r = d.getElementsByTagName(t)[0]; r.parentNode.insertBefore(s, r); }(document, 'script'));