Political ideology and DOGE layoffs
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Summary: This post reproduces Dr. Adam Bonica’s analysis into the relationship between the ideological alignment of government agencies and the targeting of layoffs by the Department of Government Efficiency (DOGE).
Credit: Dr Adam Bonica is a Professor of Political Science at Stanford University (link). He can be found on Bluesky at @adambonica.bsky.social. His original analysis was posted on Bluesky on the 20 February 2025 and can be found here.
Note: This post reproduces research relevant to public policy analysis. It presents findings without endorsing or critiquing the implications of the original research. Errors and/or omissions are the responsibility of the author.
Packages: ddplyr, ggplot2, readr and stargazer
Data: Data used in this post was drawn from the Google Sheet shared by Dr Bonica on the 22nd of February 2025.
Background
The Department of Government Efficiency (DOGE) is a temporary contracted organization with the apparent purpose to carry out Trump’s agenda of federal spending cuts and deregulation and to “modernize federal technology and software to maximize governmental efficiency and productivity”. Key initiatives include departmental spending audits, reducing diversity and inclusion programs (claiming $1 billion in savings), cutting foreign aid through USAID, offering federal workforce buyouts, and attempting to restructure the Consumer Financial Protection Bureau.
While DOGE has reported achieving savings, the actual fiscal impact of its work remains unverified. Critics, like former CBO director Douglas Holtz-Eakin, have also suggested the department’s focus is ideologically driven, targeting agencies based on political disagreement rather than efficiency metrics (source). A contention that appeared to have some support, based on analysis shared by Dr Adam Bonica on Bluesky of the association between DOGE layoffs and an agencies perceived ideological leaning (below).

Project setup
The code below loads the packages needed to reproduce the analysis and creates a number of simple functions to help us clean the agency names.
Note: The prefixes used for object names are based on this style guide.
Code: project setup
#Project Setup: Install and load necessary packages etc ---- library(dplyr) library(ggplot2) library(readr) library(stargazer) #Create functions for cleaning labels ---- #Extract text between brackets #(assumed to be parent agency of department) fnc_extract_brackets <- function(text) { matches <- regexpr("\\(([^)]+)\\)", text) has_brackets <- matches != -1 result <- ifelse(has_brackets, substring(text, matches + 1, matches + attr(matches, "match.length") - 2), NA_character_) return(result) } #Remove bracketed text fnc_remove_brackets <- function(text) { trimws(gsub("\\([^)]+\\)", "", text)) } #acronym function fnc_create_acronym<- function(texts, ignore_words = c("of", "the", "and", "in", "on", "at", "to", "for")) { sapply(texts, function(text) { words <- strsplit(trimws(text), "\\s+")[[1]] words <- words[!tolower(words) %in% tolower(ignore_words)] abbrev <- toupper(substr(words, 1, 1)) paste(abbrev, collapse="") }) }
Taking a look at the data
Taking a look at the data, the variable ‘agency’ appears to provide the name of the government body, with the parent agency listed in brackets. For instance, the entry ‘Department of the Army (DOD)’ indicates the agency is the ‘Department of the Army‘ and the parent agency is DOD (the Department of Defence). The budget and staff numbers of each agency are then listed under the ‘annual_budget_usd’ and ‘total_staff’ respectively.
Whether an agency has been targeted for layoffs or dismantling by DOGE is listed under the doge_layoffs and targeted_for_dismantling variables.
The variable perceived_ideological_estimate is sourced from research that investigated the perceived ideology of government agencies. Ranging from -2 to +2, agencies perceived as ‘liberal’ tend to have scores below 0, while those perceived as more conservative have scores above 0. Although the distribution is close to normal, there are slightly more agencies in the data set with scores above zero (54%) than below zero (46%).

Data cleaning
To make the data easier to work with, the code below makes a number of minor tweaks to the source data. Firstly, the variable names are converted to lowercase for the sake of consistency. Both the doge_layoffs and targeted_for_dismantling variables are also converted from numeric to logical to reflect them being binary. To make it easier to visualize the agency-level data the name of a government body is also abbreviated using the acronym function defined in the code above.
Code: data cleaning
#Import data ---- dta_doge<-read_csv("./Data/250222 - Agency Ideology and DOGE Firings.csv") #Data Wrangling and Cleaning ---- #change variable names to lower case names(dta_doge)<-names(dta_doge) |> tolower() #take a look at the data str(dta_doge) summary(dta_doge) #distribution of ideology scores prop.table(table(dta_doge$perceived_ideology_estimate>0)) |> round(2) hist(dta_doge$perceived_ideology_estimate) #change dummy variables to logical dta_doge<-dta_doge |> mutate(doge_layoffs= as.logical(doge_layoffs), targeted_for_dismantling= as.logical(targeted_for_dismantling)) #Clean agency name labels dta_doge<-dta_doge |> mutate(parent_agency= fnc_extract_brackets(agency), agency_name = fnc_remove_brackets(agency), agency_initials=fnc_create_acronym(agency_name) )
Political ideology vs DOGE layoffs
For the sake of brevity, we won’t precisely reproduce Adam’s plot, but focuses on the most important features. Note that the agency size presented on the Y axis uses a logarithmic scale and only organizations with staff sizes between 500 and 1,000,000 employees are presented.
If DOGE layoffs were unrelated to the ideology of an agency, we might expect as many layoffs on the right side of the dotted line to the left. However, this doesn’t appear to be the case. Instead, agencies with more ‘liberal’ ideological scores appear to have been disproportionately targeted for layoffs compared to those with more ‘conservative’ ideological scores.

Visualizing layoffs vs. ideological leaning:
#Explanatory Analysis ---- #Reproduce analysis completed by @adambonica.bsky.social's # Reproduction of @adambonica.bsky.social's plot #create filtered dataset for plot dta_plt_doge<-dta_doge |> filter(total_staff>500, total_staff<10^6) #create scatter plot with vertical line at zero perceived ideology plt_doge<-ggplot(data=dta_plt_doge, aes(x = perceived_ideology_estimate, y = total_staff)) + # Add grid lines geom_hline(yintercept = c(1000, 10000, 100000, 1000000), color = "gray90", linetype = "dashed") + geom_vline(xintercept = 0, color = "gray60", linetype = "dashed") + # Add agency acronyms colored according to DOGE layoff variable geom_text(aes(label = agency_initials, color = doge_layoffs), size=3)+ # Scale transformations scale_y_log10(breaks = c(1000, 10000, 100000, 1000000), labels = scales::comma) + scale_x_continuous(breaks = seq(-2, 2, 1)) + theme_minimal()+ theme( plot.title = element_text(face = "bold", size = 16), plot.subtitle = element_text(size = 14), plot.caption = element_text(size = 10, hjust = 0))+ # Custom colors scale_color_manual(values = c("gray60", "red"), name = "Layoff Status", labels = c("No Layoffs", "Layoffs")) + # Labels labs(title = "Empirical Evidence of Ideological Targeting in Federal Layoffs", subtitle = "Agencies seen as liberal are significantly more likely to face DOGE layoffs.", x = "Perceived Ideological Leaning\n(← More Liberal | More Conservative →)", y = "Agency Size (Number of Staff)", caption = "Note: Analysis includes only agencies with 500+ staff members. Ideology estimates are based on survey responses from 1,500+ federal executives rating agencies policy views as liberal to conservative across both Democratic and Republican administrations. Source: Richardson, Clinton, & Lewis (2018). Elite Perceptions of Agency Ideology and Workforce Skill. The Journal of Politics 80(1).") plt_doge
Does ideology predict DOGE layoffs?
To investigate this relationship further, Dr Bonica uses a OLS linear probability model to examine the extent which DOGE’s layoff decisions can be predicted by:
- How liberal or conservative an agency is perceived to be;
- How many people work at the agency; and/or
- How big the agency’s budget is.
If a factor has something to say about predicting agency layoffs by DOGE it will likely be ‘statistically significant’ in the model results. With a positive coefficient suggesting a factor increases the probability of layoffs, and a negative coefficient suggesting it decreases the probability of layoffs (see here if you’re rusty on regression).
As noted by Dr Bonica, the results paint a similar picture to the plot: agencies perceived to be more liberal are more likely to have experienced layoffs. The more conservative an agency is, the less likely it has experienced layoffs. Even after accounting for the agency’s size and annual budget.

Although the data has been updates since Adam made his first estimate, the code below produces an almost identical result to Adam. With Agency Ideology once again having the strongest predictive power across variables included in the model:
Dependent variable: | |
DOGE Layoffs | |
Agency Ideology | -0.210*** |
(0.039) | |
Log(Total Staff) | 0.020 |
(0.029) | |
Log(Annual Budget) | 0.056** |
(0.024) | |
Constant | -1.140*** |
(0.416) | |
Observations | 118 |
R2 | 0.266 |
Adjusted R2 | 0.247 |
Residual Std. Error | 0.395 (df = 114) |
F Statistic | 13.778*** (df = 3; 114) |
Note: | *p<0.1; **p<0.05; ***p<0.01 |
Code: linear probability model
#reproduce Adam's linear probability model mod_lm_doge<-lm(data=dta_doge, doge_layoffs ~ perceived_ideology_estimate + log(total_staff) + log(annual_budget_usd)) #display results summary(mod_lm_doge) stargazer(mod_lm_doge, dep.var.labels ='DOGE Layoffs', covariate.labels = c('Agency Ideology','Log(Total Staff)','Log(Annual Budget)','Constant'), type="html", digits=3, out="mod_lm_doge results.html")
Concluding remarks:
This post reproduces Dr. Bonica’s findings suggesting a significant relationship between an agency’s perceived ideology and its likelihood of facing DOGE-mandated workforce reductions. The latest dataset is available here for those interested in conducting additional analyses.
Although there’s more that can be done with the data, the main point of this post was to demonstrate how to reproduce the analysis using R. For ongoing developments in this research, including potential methodological refinements and new findings, make sure to follow the original thread and Dr Bonica himself @adambonica.bsky.social.
A note how AI was used: AI was used to draft code for the data cleaning functions and plots. AI tools were also used to improve how some ideas and concepts were communicated, but the lion’s share of grammatical and spelling errors are my own.
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.