The Effects of Shifting Priorities and Capacity on Elected Officials’ Policy Work and Constituency Service: Evidence from a Census of Legislator Requests to U.S. Federal Agencies
Author
Devin Judge-Lord
Code
# NOTE: `replication.r` is the R code extracted from `replication.qmd`---it replicates all results but does not save figures in the /figs/ folder as required to render the manuscript.# If you are not working in an RStudio project, replication.qmd may still render, # but replication.r will likely require a line pointing to the file path where you saved the dataverse files # (e.g., `here::i_am(path = "Downloads/dataverse_files")` )testing = Fverification = Tstart_time <-Sys.time()# directory to store model objects if (!dir.exists(here::here("models"))) {dir.create(here::here("models"))}# directory to store figuresif (!dir.exists(here::here("figs"))) {dir.create(here::here("figs"))}
Packages:
tidyverse and magrittr, for data wrangling
scales for plot scales
ggrepel for plot labels
here for file paths
knitr for document formatting
kableExtra for table formatting
modelsummary for regression tables
marginaleffects for predictions
fixest — statistical package for fixed effects estimation
ineq to calculate GINI coefficients
Code
requires <-c("tidyverse", "magrittr", # data wrangling"scales", # plot scales "ggrepel",# plot labels"here", # file paths "knitr", # document formatting "kableExtra", # for table formatting "modelsummary", # for regression tables "marginaleffects", # for predictions "fixest", # statistical package for fixed effects estimation "ineq", # to calculate GINI coefficients# MAY BE REQUIRED FOR QMD RENDERING"base64enc","digest","evaluate","glue","highr","htmltools","jsonlite","markdown","mime","rmarkdown","stringi","stringr","xfun","yaml")to_install <-c(requires %in%rownames(installed.packages()) ==FALSE)if(sum(to_install>0)){install.packages( requires[to_install], repos ="https://cloud.r-project.org/" )}library(modelsummary)library(marginaleffects)library(fixest)library(tidyverse)library(magrittr)library(ineq)library(kableExtra)library(ggrepel)library(scales)
load(here::here("data", "corr_counts.Rdata"))## just in case it was saved as grouped data corr_counts %<>%ungroup()# subset to 2007-2020corr_counts %<>%filter(year >2006, year <2021)# New member data load(here::here("data", "member_data.Rdata"))member_data <- member_data |>mutate(member = bioname |>str_remove(", .*") |>str_to_title() |>str_replace("cc", "cC"),member_state =paste(member, state_abbrev, sep =" (") |>paste0(")"),cqlabel =paste0("(", state_abbrev, "-", district_code, ")") |>str_remove("-0") ) d <- corr_counts %>%ungroup() %>%mutate(Type =case_when( TYPE %in%c(1,2,3) ~"Constituency\nService", TYPE %in%c(4,5) ~"Policy"), type =case_when( TYPE ==1~"Constituent (individual)", TYPE ==2~"Constituent (corporate)", TYPE ==3~"Constituent (501c3 or local\n government)", TYPE ==4~"Policy (corporate)", TYPE ==5~"Policy (general)" )) type <- d %>%group_by(Type) %>%summarise(n =sum(per_icpsr_chamber_year_agency_type)) %>%ungroup()percent <-function(x){ y <- x*100 y %<>%round() return(y)}year_congress<-function(year){return(floor((year -1787)/2))}d %<>%mutate(congress =year_congress(year))dcounts <- d |>left_join(member_data)
Descriptive
We hand-coded data on 611,239 instances of members of Congress contacting federal agencies.
Types of Legislator Requests
84% of the average legislators’ contacts with agencies are about constituency service.
16% of the average legislators’ contacts with agencies are about policy work.
Percents by Type
We classify legislator requests into five overall types.
Results in manuscript (Figure 2, p. 22)
Code
# paper figure type_totals <- d %>% tidyr::drop_na(Type) %>%mutate(total =sum(per_icpsr_chamber_year_agency_type)) %>%group_by(total, Type, type) %>%summarise(nT =sum(per_icpsr_chamber_year_agency_type)) %>%mutate(percent =paste0(nT, " = ", 100*round(nT/total, 2), "%"),type =str_c(type, "\n ", percent)) %>%ungroup() %>%group_by(Type) %>%mutate(nt =sum(nT),percent_t =paste0(100*round(nt/total, 2), "%"))type_totals %<>%mutate(type = type %>%# FOR AJPS - remove N and percent str_remove_all("\n .*") %>%# END FOR AJPS str_replace_all("\\)", "") %>%str_replace_all(" \\(", ",\n") ) %>%ungroup()N <- type_totals$total |>unique()# horizontaltype_totals %>%ungroup() %>%ggplot() +geom_col(alpha = .7,aes(x = type, fill = Type, y = nT) ) +scale_y_continuous(breaks =seq.int(0,500000, by =100000), limits =c(0,400000), labels = scales::label_comma() ) +labs(x ="",fill ="",y =paste("Number of contacts"),title ="") +#geom_text(aes(label = Type, x = Type,y = nT) ) + theme(panel.border =element_blank(),panel.grid.major.x =element_blank(),axis.ticks =element_blank(),#axis.text.x.top = element_text(),legend.position ="none") + ggpubr::geom_bracket(label.size =3, # FOR AJPSxmin = type_totals$type[1], xmax = type_totals$type[3], y.position =380000,label =paste(type_totals$percent_t[1], "Constituency service" ),#hjust = 1,vjust =-1 ) + ggpubr::geom_bracket(label.size =3, # FOR AJPSxmin = type_totals$type[4], xmax = type_totals$type[5], y.position =85000,label =paste(type_totals$percent_t[5], "Policy work"),#hjust = 1,vjust =-1 )+scale_fill_viridis_d(option ="cividis", end = .8, direction =-1)
# A tibble: 2 × 2
chamber chamber_average
<chr> <dbl>
1 House 54.3
2 Senate 148.
Results in manuscript (Figure 3, p. 24)
Code
percentiles |>arrange(rank) |>head()
# A tibble: 6 × 5
# Groups: chamber [2]
member_state Percentile mean chamber rank
<chr> <int> <dbl> <chr> <int>
1 Byrd (WV) 100 538. Senate 1
2 Wolf (VA) 100 381. House 1
3 Comstock (VA) 100 349. House 2
4 Nelson (FL) 99 535. Senate 2
5 Donovan (NY) 100 244. House 3
6 Webb (VA) 98 533. Senate 3
Code
percentiles %>%filter(chamber =="Senate") %>%ggplot() +geom_col(aes(x = Percentile, y = mean), color ="grey", width = .000001,fill ="black",position ="dodge") +geom_point(aes(x = Percentile, y = mean), color ="light blue") +geom_text(aes(x = Percentile, y = mean, label =ifelse(rank <24| Percentile <50, member_state, "" ) ), check_overlap = T, size =3,hjust ="inward") +# theme_minimal() + labs(#title = "Average Legislator Requests per Year by Percentile",x ="Percentile in the Senate",y ="Average requests per year")
Code
percentiles %>%filter(chamber =="House") %>%ggplot() +geom_col(aes(x = Percentile, y = mean), color ="grey", width = .000001,fill ="black",position ="dodge") +geom_point(aes(x = Percentile, y = mean), color ="light blue") +geom_text(aes(x = Percentile, y = mean, label =ifelse(rank <24| Percentile <50, member_state, "")), check_overlap = T, size =3,hjust ="inward") +# theme_minimal() + labs(#title = "Average Legislator Requests per Year by Percentile",x ="\nPercentile in the House",y ="Average requests per year")
Requests by Year
Code
#counts-per-yeardcounts_per_legislator <- dcounts %>%group_by(bioname, year) %>%mutate(per_bioname_year =sum(per_icpsr_chamber_year_agency_type)) %>%ungroup() schumer2013 <- dcounts_per_legislator %>%filter(bioname =="SCHUMER, Charles Ellis (Chuck)", year ==2013) %>% .$per_bioname_year %>%unique()cruz2013 <- dcounts_per_legislator %>%filter(bioname =="CRUZ, Rafael Edward (Ted)", year ==2013) %>% .$per_bioname_year %>%unique()mcconnell2013 <- dcounts_per_legislator %>%filter(bioname =="McCONNELL, Addison Mitchell (Mitch)", year ==2013) %>% .$per_bioname_year %>%unique()# plot a line for all legislator-year counts in the data (this is a lot of data points and thus takes a long time to render)p <- dcounts_per_legislator %>%filter(year >2006, year <2018) %>%distinct(bioname, per_bioname_year, year, chamber) %>%filter(per_bioname_year >0) %>%ggplot() +geom_line(aes(x = year, y = per_bioname_year, group = bioname, color = chamber), alpha = .1) +geom_line(aes(x = year, group = bioname, color = chamber,y =ifelse(bioname =="SCHUMER, Charles Ellis (Chuck)", per_bioname_year, NA))) +geom_label(x =2013, y = schumer2013, label ="Chuck Schumer") +geom_line(aes(x = year, group = bioname, color = chamber,y =ifelse(bioname =="CRUZ, Rafael Edward (Ted)", per_bioname_year, NA))) +geom_label(x =2013, y = cruz2013, label ="Ted Cruz") +geom_line(aes(x = year, group = bioname, color = chamber,y =ifelse(bioname =="McCONNELL, Addison Mitchell (Mitch)", per_bioname_year, NA))) +geom_label(x =2013, y = mcconnell2013, label ="Mitch McConnell") +labs(x ="",color =" ",y =paste("Requests per legislator per year"),title ="") +scale_x_continuous(breaks =unique(dcounts$year)) +scale_color_viridis_d(begin =0, end = .6, option ="cividis", direction =-1) # Non-AJPS formatting # p + # theme_minimal() + # theme(axis.text.x = element_text(angle = 30, vjust = 0) ) # FOR AJPS p +theme(panel.background =element_blank(), legend.position ="inside",#FIXME NOTE: legend justification requires ggplot2 v3.5 or higher https://stackoverflow.com/questions/78212838/error-when-running-code-examples-from-usmap-r-packagelegend.justification.inside =c(1, 1), #legend.position.inside = c(1, 1),axis.ticks =element_blank() )
Example
Rep. Barbara Comstock worked in Rep. Frank Wolf’s congressional office for five years, described him as a “longtime mentor,” and claimed that Wolf first urged her to run for office. He endorsed and campaigned with her.
Notice several patterns - dip in constituency service when Wolf is no longer running for re-election - further dip with transition - quick rebound as Comstock gets her office in order - inheriting a highly effective office, Comstock is far above average House member
Code
case_study <-function(cq){ CHAMBER <-filter(member_data, cqlabel == cq) %>% .$chamber %>% .[1]dcounts %>%group_by(member_state, year, chamber, cqlabel) %>%summarise(n =sum(per_icpsr_chamber_year_agency_type)) %>%ungroup() %>%group_by(chamber) %>%mutate(mean_per_chamber =mean(n) %>%round(0)) %>%filter(cqlabel == cq, year >2007, year <2017) %>%ggplot() +aes(x = year, y = n, fill = member_state %>%str_replace("-.*", "\\)")) +geom_col(alpha = .5, position ="dodge") +geom_hline(aes(yintercept = mean_per_chamber), linetype =2) +geom_text(aes(y = mean_per_chamber), x =2007.5, label ="Chamber average", check_overlap = T,size =3, vjust =1.3, hjust =0) +scale_x_continuous(breaks =seq(2008, 2016, 1)) +labs(x ="",y ="Number of requests", fill ="") +# str_c(CHAMBER, "-", cq) %>% str_remove_all("\\(|\\)|NA") ) +theme(panel.grid.major.x =element_blank(), legend.position ="bottom",axis.title.x =element_text(margin =unit(c(-5, 0, 0, 0), "mm")),# # FOR AJPS# axis.text.x = element_text(angle = 45), # # END AJPS panel.grid.minor.x =element_blank() )+scale_fill_viridis_d(begin =0, end = .6, option ="cividis", direction =-1) }
# make icpsr year variable d %<>%mutate( icpsr_year =paste(icpsr, year, sep='_') )## chamber switchers in original data (party switchers are not an issue because they net new ICPSR ids)chamber_switchers <- d |>distinct(icpsr_year, agency, chamber) |>add_count(icpsr_year, agency, #party, name ="n") |>filter(n >1) |>distinct(icpsr_year, chamber) |>arrange(icpsr_year)# DROP CHAMBER SWITCHERSd %<>%filter(!icpsr_year %in% chamber_switchers$icpsr_year)############################# add covariates for models ############################## congress year converters congress_years<-function(congress){ years<-c(congress*2+1787, congress*2+1788 )return(years)}year_congress<-function(year){return(floor((year -1787)/2))}# make congress to merge with member data d$congress<-year_congress(d$year)# inspect duplicates d <- d |>ungroup() |>distinct() |>add_count(icpsr, year, agency, #party, name ="n") if(testing){d |>filter(n >1) |>distinct(icpsr, year) } # LEFT join in member data d <- d |>ungroup() |>left_join(member_data, by =c('congress', 'icpsr', "chamber") ) ## count or repeated values (chamber and party switchers)# note that in the full data, we use the dates of letters to attribute them to the proper party or chamber at the time# but in yearly counts, we lose this level of detail, leading to undercounts for switchers# # inspect for duplicates if(testing){d <- d |>ungroup() |>distinct() |>add_count(icpsr, year, agency, #party, name ="n") d |>filter(n >1) |>distinct(icpsr, year) }
Code
# This chunk takes the minimal count data and creates legislator-level and district-level yearly count and ratio data# These are then used to estimate the models# the key DVs are# - perYear = counts per year (member level and district level)# - ratio = ratio of policy work to constituency service##################### TRANSFORMATIONS # #################### tenure in office for experience tests d <- d |>group_by(icpsr) |>mutate(tenure = year - first_year,first =ifelse(tenure==0, 1, 0),second =ifelse(tenure==1, 1, 0),third =ifelse(tenure==2, 1, 0),fourth =ifelse(tenure==3, 1, 0),fifth =ifelse(tenure==4, 1, 0),sixth =ifelse(tenure==5, 1, 0),max_year =max(tenure) ) # two-way fixed effects d <- d |>ungroup() |>mutate(icpsr_agency =paste(agency, icpsr, sep='_'),agency_year =paste(agency, year, sep='_') )# indicator for whether they survived their first election d <- d |>mutate(survive =ifelse( chamber =='House'& max_year>1| chamber=='Senate'& max_year>5,1, 0) )dcounts_tenure <- d########## RATIO # ######### ## the ratio variable - at the legislator-year level ## (not the legislator-year-agency level like above)dcounts_ratio <- d |>ungroup() |># variables for ratio models group_by(year, icpsr, chamber, chair, ranking_minority, majority, presidents_party, first, second, third, fourth, fifth, sixth) |>summarise(perCon =sum(perYear_con), perPol =sum(perYear_policy)) |>mutate(ratio = perCon/(perCon + perPol))#### PER DISTRICT COUNTS ######################d %<>%mutate(decade =case_when( year <2011~'0', year >2010~'1'))d %<>%mutate(state_dist =case_when( chamber=='Senate'~paste(state,district_code, sep='_' ), chamber =='House'~paste(paste(state, district_code, sep='_'), decade, sep='_')))dcounts_per_district<- d |>group_by(year, state_dist, icpsr, chamber, tenure, first, second, third, fourth, fifth, sixth, state) |>summarise(perYear =sum(perYear),perYear_con =sum(perYear_con),perYear_policy =sum(perYear_policy)) |>distinct()# rename first year as "new_member" dcounts_per_district %<>%mutate(new_member = first)
Defining Prestige Committees
All of these findings replicate with various interpretations of “prestige” committees. To measure committee prestige, we use a revealed preference approach–what do members think is most valuable–using party rules/norms that limit members to serving on only one of a small number of desirable committees. For House members, the “exclusive” committees are: Appropriations, Energy & Commerce, Financial Services, Rules, and Ways & Means (CRS 2022). For Senators, the exclusive (also called “Super A”) Committees are: Appropriations, Armed Services, Finance, and Foreign Relations (CRS 2024).
# check n per year dcounts_tenure %>%filter(year >2006) %>%group_by(year) %>%tally(perYear) |>kablebox_long()
year
n
2007
23368
2008
35688
2009
44615
2010
48212
2011
49537
2012
43473
2013
43430
2014
45609
2015
41503
2016
43352
2017
32911
2018
134375
2019
12896
2020
11023
Code
# average per memberdcounts_tenure %>%left_join(member_data %>%distinct(bioname, icpsr)) %>%group_by(bioname, year) %>%summarise(perYear =sum(perYear)) %>%group_by(bioname) %>%summarise(average_per_year =mean(perYear), average_per_year) |>arrange(-average_per_year) |>kablebox()
bioname
average_per_year
BYRD, Robert Carlyle
538.5000
NELSON, Clarence William (Bill)
535.2500
WEBB, James H. (Jim)
532.6667
SCHUMER, Charles Ellis (Chuck)
519.7143
WARNER, Mark
425.6667
LUGAR, Richard Green
417.0000
MIKULSKI, Barbara Ann
403.3000
McCAIN, John Sidney, III
396.4167
GILLIBRAND, Kirsten
387.1667
TOOMEY, Patrick Joseph
386.1000
WOLF, Frank Rudolph
380.8750
RUBIO, Marco
376.8000
GRASSLEY, Charles Ernest
366.0714
DURBIN, Richard Joseph
358.4286
SPECTER, Arlen
350.5000
COMSTOCK, Barbara J.
349.2500
BROWN, Sherrod
318.7857
OBAMA, Barack
318.5000
ISAKSON, Johnny
306.7857
BOOKER, Cory Anthony
301.7500
CHAMBLISS, Saxby
301.6250
CORNYN, John
296.6429
CASEY, Robert (Bob), Jr.
294.0714
HAGAN, Kay
281.3333
MANCHIN, Joe, III
280.6667
SHELBY, Richard C.
261.2143
LEVIN, Carl
256.8750
KLOBUCHAR, Amy
255.8571
SHAHEEN, Jeanne
253.5833
FEINSTEIN, Dianne
249.8571
KAINE, Timothy Michael (Tim)
245.3750
DONOVAN, Daniel M., Jr.
243.7500
KIRK, Mark Steven
243.3750
CURBELO, Carlos
240.0000
HARRIS, Kamala Devi
238.5000
TILLIS, Thomas Roland (Thom)
237.3333
SOTO, Darren Michael
234.7500
BURR, Richard M.
231.2857
CARDIN, Benjamin Louis
228.0714
KOHL, Herbert H.
228.0000
BOXER, Barbara
227.5000
FEINGOLD, Russell Dana
226.0000
VAN HOLLEN, Christopher
224.5000
SESTAK, Joe
224.0000
WARNER, John William
220.0000
WARREN, Elizabeth
218.3750
GRAHAM, Lindsey O.
218.1429
COLLINS, Susan Margaret
218.0000
RODRIGUEZ, Ciro D.
216.0000
MENG, Grace
215.5000
SMITH, Tina
209.0000
ALEXANDER, Lamar
202.5714
LANDRIEU, Mary L.
197.6250
SNOWE, Olympia Jean
197.1667
McCAUL, Michael T.
196.9286
PORTMAN, Robert Jones (Rob)
192.9000
REID, Harry
192.5000
BLUMENTHAL, Richard
190.6000
GRAHAM, Gwendolyn (Gwen)
190.5000
GOODLATTE, Robert William
189.1667
STEFANIK, Elise M
188.1667
HUTCHISON, Kathryn Ann Bailey (Kay)
183.3333
BINGAMAN, Jesse Francis, Jr. (Jeff)
181.5000
MURRAY, Patty
180.2857
BEYER, Donald Sternoff Jr.
179.8333
MacARTHUR, Thomas Charles
174.7500
WYDEN, Ronald Lee
173.2857
McCASKILL, Claire
172.8333
McCONNELL, Addison Mitchell (Mitch)
172.1429
HATCH, Orrin Grant
171.7500
O'ROURKE, Beto
171.6667
DAVIS, Rodney
170.2500
TAYLOR, Scott William
170.0000
ERNST, Joni
168.6667
CORKER, Robert (Bob)
167.9167
VISCLOSKY, Peter
167.5714
CORTEZ MASTO, Catherine Marie
167.5000
STABENOW, Deborah Ann
165.3571
MARTINEZ, Melquiades R. (Mel)
162.2500
CARTER, Buddy
161.6667
DAVIS, Lincoln
160.5000
VITTER, David
160.1000
FASO, John J.
160.0000
HARKIN, Thomas Richard (Tom)
159.7500
MOULTON, Seth
157.1667
DUCKWORTH, Tammy
156.8750
REED, John F. (Jack)
156.7143
FORBES, J. Randy
156.5000
BROWN, Anthony Gregory
156.2500
BAUCUS, Max Sieben
153.0000
COSTELLO, Ryan
151.7500
ESPAILLAT, Adriano J.
151.2500
KERRY, John Forbes
147.0000
ALEXANDER, Rodney
146.3750
KHANNA, Rohit
146.2500
DODD, Christopher John
146.0000
BALDWIN, Tammy
145.7143
GARRETT, Scott
145.3000
STEVENS, Theodore Fulton (Ted)
144.0000
SHIMKUS, John M.
143.7143
Code
# average per member per agency dcounts_tenure %>%left_join(member_data %>%select(bioname, icpsr)) %>%group_by(bioname) %>%summarise(average_per_year_per_agency =mean(perYear)) |>arrange(-average_per_year_per_agency) |>kablebox()
bioname
average_per_year_per_agency
BYRD, Robert Carlyle
9.324675
SCHUMER, Charles Ellis (Chuck)
9.027295
WEBB, James H. (Jim)
8.732240
NELSON, Clarence William (Bill)
8.298450
WARNER, Mark
7.286733
LUGAR, Richard Green
6.836066
GILLIBRAND, Kirsten
6.832353
TOOMEY, Patrick Joseph
6.714783
RUBIO, Marco
6.553044
HARRIS, Kamala Devi
6.489796
SOTO, Darren Michael
6.387755
GRASSLEY, Charles Ernest
6.358561
DURBIN, Richard Joseph
6.225807
McCAIN, John Sidney, III
6.145995
MIKULSKI, Barbara Ann
6.119879
OBAMA, Barack
6.066667
WOLF, Frank Rudolph
5.998031
SMITH, Tina
5.687075
BROWN, Sherrod
5.537221
BOOKER, Cory Anthony
5.486364
ISAKSON, Johnny
5.328784
COMSTOCK, Barbara J.
5.251880
CORNYN, John
5.152605
CASEY, Robert (Bob), Jr.
5.107940
MANCHIN, Joe, III
4.804565
TILLIS, Thomas Roland (Thom)
4.778524
CHAMBLISS, Saxby
4.750000
CORTEZ MASTO, Catherine Marie
4.557823
SHELBY, Richard C.
4.537221
KIM, Andy
4.500000
KAINE, Timothy Michael (Tim)
4.461364
KLOBUCHAR, Amy
4.444169
SHAHEEN, Jeanne
4.340941
FEINSTEIN, Dianne
4.339950
BROWN, Anthony Gregory
4.251701
WARNER, John William
4.190476
HAGAN, Kay
4.188586
ESPAILLAT, Adriano J.
4.115646
LEVIN, Carl
4.045276
SPECTER, Arlen
4.028912
BURR, Richard M.
4.017370
KHANNA, Rohit
3.979592
WARREN, Elizabeth
3.970455
CARDIN, Benjamin Louis
3.961539
MENG, Grace
3.918182
FEINGOLD, Russell Dana
3.913420
VAN HOLLEN, Christopher
3.899504
SESTAK, Joe
3.878788
GRAHAM, Lindsey O.
3.789082
STEFANIK, Elise M
3.788591
COLLINS, Susan Margaret
3.786601
MAST, Brian Jeffery
3.761905
RODRIGUEZ, Ciro D.
3.740260
KOHL, Herbert H.
3.737705
DONOVAN, Daniel M., Jr.
3.665414
SUOZZI, Thomas
3.653061
KIRK, Mark Steven
3.652908
BEYER, Donald Sternoff Jr.
3.620805
CURBELO, Carlos
3.609023
CRIST, Charlie Joseph Jr.
3.571429
MALINOWSKI, Tomaz
3.531250
ALEXANDER, Lamar
3.518610
GAETZ, Matthew L. II
3.517007
GOMEZ, Jimmy
3.503401
McBATH, Lucy
3.468750
BOXER, Barbara
3.452200
McCAUL, Michael T.
3.420596
ERNST, Joni
3.395973
PORTMAN, Robert Jones (Rob)
3.354783
BLUMENTHAL, Richard
3.314783
CARTER, Buddy
3.255034
PANETTA, James Varni
3.251701
SNOWE, Olympia Jean
3.232240
JAYAPAL, Pramila
3.231292
MOULTON, Seth
3.164429
RASKIN, Jamie Ben
3.156463
MURRAY, Patty
3.131514
LANDRIEU, Mary L.
3.112205
DAVIS, Rodney
3.095455
GOTTHEIMER, Josh S.
3.034014
GONZALEZ, Vicente Jr.
3.027211
WYDEN, Ronald Lee
3.009926
HUTCHISON, Kathryn Ann Bailey (Kay)
3.005464
McCONNELL, Addison Mitchell (Mitch)
2.990074
BINGAMAN, Jesse Francis, Jr. (Jeff)
2.975410
TAYLOR, Nicholas
2.968750
TAYLOR, Scott William
2.956522
GOODLATTE, Robert William
2.932816
REID, Harry
2.921093
VISCLOSKY, Peter
2.910670
BRAUN, Michael
2.906250
STABENOW, Deborah Ann
2.872208
DUCKWORTH, Tammy
2.852273
TRAHAN, Lori
2.843750
KRISHNAMOORTHI, S. Raja
2.816327
ARRINGTON, Jodey Cook
2.809524
MARTINEZ, Melquiades R. (Mel)
2.809524
FASO, John J.
2.782609
DAVIS, Lincoln
2.779221
STEVENS, Theodore Fulton (Ted)
2.742857
Code
# per member per agency dcounts_tenure %>%left_join(member_data %>%distinct(bioname, icpsr)) %>%group_by(bioname, agency) %>%summarise(per_year_per_agency = perYear) |>arrange(-per_year_per_agency) |>kablebox()
# total per legislator-agency pair dcounts_tenure %>%group_by(Legislator_x_Agency) %>%summarise(n = perYear %>%sum()) %>%arrange(-n) %>%kablebox()
Legislator_x_Agency
n
VA_15039
2158
VA_40915
1694
VA_94659
1691
VA_14858
1654
DHHS_CMS_40909
1579
DHS_USCIS_15021
1481
DHS_USCIS_21342
1450
DHS_USCIS_41102
1431
DHS_USCIS_20733
1373
DHS_USCIS_40700
1335
VA_29718
1297
VA_20530
1281
VA_29935
1210
DHS_USCIS_20316
1209
DHS_USCIS_29386
1084
VA_14440
1070
DHS_14858
1058
VA_15021
1045
DHS_USCIS_20735
1042
DHS_USCIS_14858
1038
DHS_USCIS_29909
1031
VA_29512
1029
VA_14869
949
DHS_USCIS_41301
947
DHS_USCIS_40906
935
VA_20330
918
DHS_USCIS_29935
917
VA_29566
915
DHS_USCIS_29741
912
DHS_USCIS_41504
892
DHS_USCIS_29389
866
DHS_USCIS_21343
860
DHS_USCIS_21560
856
DHS_USCIS_29348
854
DHHS_CMS_20336
853
DHS_USCIS_14651
833
DHS_USCIS_41701
833
DHS_USCIS_29134
818
DHS_USCIS_20330
801
VA_40305
796
DHS_USCIS_29378
793
DHHS_CMS_14226
789
DHS_USCIS_29776
772
DHS_USCIS_20707
768
DHS_USCIS_41305
768
DHS_USCIS_41706
758
DHS_USCIS_15408
746
DHS_USCIS_40703
744
DHS_USCIS_21512
740
DHS_USCIS_40305
731
VA_15408
726
DHHS_CMS_14921
719
DHS_USCIS_20952
706
DHS_USCIS_29925
699
HUD_14651
690
VA_21328
686
DHHS_CMS_14506
684
NARA_41308
678
DHS_USCIS_20923
650
VA_14226
640
DHS_USCIS_41308
639
DHHS_CMS_14503
633
DHHS_CMS_14440
621
DHS_USCIS_14871
612
DHS_USCIS_21538
590
DHHS_CMS_29548
577
VA_1366
575
DHS_USCIS_29377
573
DHS_USCIS_29142
571
DHS_USCIS_29548
570
DHS_USCIS_41700
568
DHS_USCIS_21325
559
DHS_USCIS_21555
559
DHS_USCIS_29379
556
VA_40706
556
DHS_USCIS_20542
554
DHS_USCIS_21728
547
DHS_USCIS_40705
545
HUD_49300
542
DHHS_CMS_41102
541
DHS_USCIS_21122
541
HUD_29909
539
VA_21746
539
NARA_21111
537
DHS_USCIS_15019
534
DHHS_CMS_94659
533
VA_41502
533
DHS_15000
532
DHS_USCIS_29337
531
DHS_40706
526
DHS_USCIS_21715
526
HUD_20735
525
DHS_USCIS_21361
523
VA_29771
512
DHS_USCIS_21326
508
DHS_USCIS_40304
501
DHS_USCIS_29312
499
DHS_USCIS_29732
499
DHS_USCIS_21754
498
VA_29909
496
Values for Predictions
The most frequent legislator agency pair: McCain x VA with 2159 letters!
The average is 84 letters per legislator per year, 1.38 letters per agency per year. For predictions, we need an average member-year-agency triad. The first table below shows the members who averaged 84, entered Congress between 2007 and 2011, were observed in our data for at least seven years, and most often submitted exactly one letter to an agency (the closest integer 84 ). For realism, this person would ideally become a chair at some point in our data.
We use fixest::feglm here and replicated the main models using xtreg in Replication.do. See more about how robust (clustered) standard errors with fixed effects are calculated by fixesthere and by xtreghere.
Code
# Coef Mapcm =c("chair"="Committee Chair","ranking_minority"="Ranking Member","prestigeR2"="Prestige Committee (R2)","prestigeOLD"="Prestige Committee (Old)","prestige"="Prestige Committee","new_member"="New Member", "new_senator"=" New Senator in Delegation","new_one"=" New Member in Delegation","new_proportion"=" New Proportion in Delegation","new_member:same_party"=" New Member x Same Party", "first"="First Year","second"="Second Year","third"="Third Year","fourth"="Fourth Year","fifth"="Fifth Year","sixth"="Sixth Year","same_party:second"="Second Year x Same Party","same_party:third"="Third Year x Same Party","same_party:fourth"="Fourth Year x Same Party","same_party:fifth"="Fifth Year x Same Party","same_party:sixth"="Sixth Year x Same Party","same_party"="Same Party","majority"="Majority","presidents_party"="President's party","Legislator"="Legislator", "Agency"="Agency","Num.Obs."="Observations" )# FORMATTING FOR AJPS cmAJPS <- cm |>str_to_sentence()names(cmAJPS) <-names(cm)cm <- cmAJPS# END FORMATTING FOR AJPS # set fixed effects mapping setFixest_dict(cm)format_n <-function(x) format(round(x, 3), big.mark=",") # this worksf <-function(x) stringr::str_replace(x, "[A-z]", "✓") #FIXME not sure why this is not workinggm <-list(list("raw"="nobs", "clean"="Observations", "fmt"= format_n),list("raw"="FE: Year_x_Agency", "clean"="Year x agency fixed effects", "fmt"= f),list("raw"="FE: Legislator_x_Agency", "clean"="Legislator x agency fixed effects", "fmt"= f),list("raw"="FE: icpsr_agency", "clean"="Legislator-agency fixed effects", "fmt"= f),list("raw"="FE: District", "clean"="District fixed effects", "fmt"= f),list("raw"="FE: Year", "clean"="Year fixed effects", "fmt"= f),list("raw"="FE: Legislator.*x.*Agency", "clean"="Legislator x agency fixed effects", "fmt"= f),list("raw"="FE: Year.*x.*Agency", "clean"="Year x agency fixed effects", "fmt"= f),list("raw"="FE: Legislator", "clean"="Legislator fixed effects", "fmt"= f) )
Total Letters
Member-level Coefficient Plots
Figures: figs/m-total-[1:4].png
Code
# paper table 2# Model 1 # cross-sectional m_total_cross <-feglm (perYear ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency,cluster ="Legislator", data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_total_cross)}coefplot(m_total_cross, horiz = T, drop ="(Intercept)") # Model 2m_total_dnd <-feglm (perYear ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator",# ALT vcov = hetero ~ ssc(cluster.adj = TRUE),data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_total_dnd)}coefplot(m_total_dnd, horiz = T) # 3m_total_2nd <-feglm (perYear ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator", data = dcounts_tenure %>%filter(survive ==1))if(testing){modelsummary::modelsummary(m_total_2nd)}coefplot(m_total_2nd, horiz = T) # 4m_logtotal_dnd <-feglm (log(perYear +1) ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator", data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_logtotal_dnd)}coefplot(m_logtotal_dnd, horiz = T)
1
2
3
4
m-total-[1:4].png
Total Letters Table
Models: models/models_total.Rdata
Code
models_total <-list("(1)"= m_total_cross,"(2)"= m_total_dnd,"(3)"= m_total_2nd,"(4)"= m_logtotal_dnd)rows <-tibble(term =c("Dependent variable", "Majority","President's party","All legislators", "Served at least 2nd term"),`(1)`=c("Count", "✓", "✓", "✓", ""),`(2)`=c("Count", "✓", "✓", "✓", ""),`(3)`=c("Count", "✓","✓","", "✓"),`(4)`=c("Log(Count+1)","✓","✓", "✓", "") )rows <-tibble(term =c("Dependent variable", #"Majority",#"President's party","All legislators", "Served at least 2nd term"),`(1)`=c("Count", "✓", ""),`(2)`=c("Count", "✓", ""),`(3)`=c("Count","", "✓"),`(4)`=c("Log(Count+1)", "✓", "") )attr(rows, 'position') <-c(0, 20,21,22,23)attr(rows, 'position') <-c(0, 24,25)# HTMLmodelsummary(models_total,notes =list("Robust standard errors in parentheses, clustered by legislator.","This table shows estimates of the effect of institutional power on levels of constituency service. All coefficients represent the average additional requests per year per agency; per legislator, per year effects are simply these coefficients times the number of agencies in the data."))
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by legislator.
This table shows estimates of the effect of institutional power on levels of constituency service. All coefficients represent the average additional requests per year per agency; per legislator, per year effects are simply these coefficients times the number of agencies in the data.
To address potential confounding in across-legislator comparisons, the estimates from Model 2 (Column 2 of Table @tbl-models_total) provide the estimated effects from the difference-in-differences specification in Equation @eq-diff1. Across all measures of institutional power, we find that more power increases the number of requests that legislators make. Consider first the effect of being a committee chair. We estimate that becoming a committee chair causes an increase of 0.25 requests per agency (95-percent confidence interval [0.07, 0.43]). Across all 92 agencies, this represents an increase of approximately 23 additional requests per year, 27.27% of the average requests per year in our data. There is a smaller increase for individuals who become ranking members and those who join a Prestige Committee, though the increase is statistically significant for the Prestige Committee. Becoming a ranking member of a committee causes an increase of 0.17 contacts per agency, while joining a prestige committee causes an 0.25 per agency increase in the number of contacts a member of Congress makes.
We estimate that the experience gained between the first and second year in Congress causes an increase of 0.09 requests per agency. The experience gained between the first and seventh year causes an increase of 0.49 per agency. Across all n_agency agencies, this represents an increase of approximately 45 additional requests per year, 35% of the average requests per year in our data. There is a smaller increase after the second year. The experience gained between the second and seventh year causes an increase of 0.4 per agency, an increase of approximately 36 additional requests per year, 29% of the average requests per year in our data.
Total Letters Predictions
Figures: figs/m-total-predicted-[1:4].png
Code
predicted <-predictions(m_total_cross,newdata = values)# Cross-sectional predictionspredicted %>%mutate(estimate = estimate*n_agency, conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%ggchair() +labs(#title = "", # "Predicted total letters per year\n(cross-sectional)",x ="",y ="Predicted total letters per year",fill ="",color ="",shape ="") # by tenurepredicted <-predictions(m_total_cross,newdata = values_tenure)predicted %>%mutate(estimate = estimate*n_agency, conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%ggtenure() +labs(#title = "", # "Predicted total letters per year\n(cross-sectional)",x ="Years serving in Congress",y =" Predicted letters per year",fill ="",color ="",shape ="") # diff in diff predicted <-predictions(m_total_dnd,newdata = values)# Predictions by Chair and President's Partypredicted %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency)) %>%ggchair() +labs(#title = "", # "Predicted total letters per year\nDifference in Differences (Within-Legislator)",x ="",y =" Predicted letters per year",fill ="",color ="",shape ="") # by tenurepredicted2 <-predictions(m_total_dnd,newdata = values_tenure)predicted2 %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency) %>%ggtenure() +geom_line(aes(x =as.numeric(year_in_congress %>%str_sub(1,1) %>%str_replace("N", "1")))) +labs(#title = "", # "Predicted total letters per year\nDifference in Differences (Within-Legislator)",x ="Years serving in Congress",y =" Predicted letters per year",fill ="",color ="",shape ="")
Table @tbl-models_con is identical to Table @tbl-models_total except that we subset the data to only legislator requests hand-coded as constituency service. Column 2 of Table @tbl-models_con provides the estimated effects from the difference-in-differences specification in Equation @eq-diff1. More experience increases the level of constituency service that legislators provide. The effect of being a committee chair is positive but not significant at the .05 level. We estimate that the experience gained between the first and second year in Congress causes an increase of 0.02 requests per agency. The experience gained between the first and seventh year causes an increase of 0.25 per agency. Across all 92 agencies, this represents an increase of approximately 23 additional requests per year, 26% of the average requests per year in our data. There is a smaller increase after the second year. The experience gained between the second and seventh year causes an increase of 0.24 per agency, an increase of approximately 22 additional requests per year, 24% of the average requests per year in our data.
Constituency Service Predictions
Figures: figs/m-con-predicted-[1:4].png
Code
# Cross-sectional predictions:predicted <-predictions(m_con_cross,newdata = values)# A plot by chair & presidents' partypredicted %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency)) %>%ggchair() +labs(#title = "", # "Predicted Constituency Service Letters per year\n(cross-sectional)",x ="",y =" Predicted letters per year",fill ="",color ="",shape ="") # by tenurepredicted <-predictions(m_con_cross,newdata = values_tenure)predicted %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency) %>%ggtenure() +# geom_line(aes(x = as.numeric(year_in_congress %>% str_sub(1,1)))) + labs(#title = "", # "Predicted Constituency Service Letters Per year\n(Cross Sectional)",x ="Years serving in Congress",y =" Predicted letters per year",fill ="",color ="",shape ="") # Diff in diff predictions predicted <-predictions(m_con_dnd,newdata = values)# diff in diff plotpredicted %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency)) %>%ggchair() +labs(#title = "", # "Predicted Constituency Service Letters per year\nDifference in Differences (Within-Legislator)",x ="",y =" Predicted letters per year",fill ="",color ="",shape ="") # by tenurepredicted <-predictions(m_con_dnd,newdata = values_tenure)predicted %>%mutate(estimate = estimate*n_agency, #predicted*n_agency,conf.high = conf.high*n_agency, conf.low = conf.low*n_agency) %>%# std.error = std.error*n_agency) %>%ggtenure() +geom_line(aes(x =as.numeric(year_in_congress %>%str_sub(1,1)))) +labs(#title = "", # "Predicted Constituency Service Letters Per year\nDifference in Differences (Within-Legislator)",x ="Years serving in Congress",y =" Predicted letters per year",fill ="",color ="",shape ="")
1
2
3
4
m-con-predicted
Policy Work
Member-level Policy Work Coefficient Plots
Only using letters coded as constituent letters
Figures: figs/m-policy-[1:4].png
Code
m_policy_cross <-feglm (perYear_policy ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency,cluster ="Legislator", data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_policy_cross)}coefplot(m_policy_cross, horiz = T, drop ="(Intercept)") # 2m_policy_dnd <-feglm (perYear_policy ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator",data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_policy_dnd)}coefplot(m_policy_dnd, horiz = T) # 3m_policy_2nd <-feglm (perYear_policy ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator", data = dcounts_tenure %>%filter(survive ==1))if(testing){modelsummary::modelsummary(m_tenure_2nd)}coefplot(m_policy_2nd, horiz = T) # 4m_logcon_dnd <-feglm (log(perYear_policy +1) ~ chair + ranking_minority + prestige + first + second + third + fourth + fifth + sixth + majority + presidents_party | Year_x_Agency + Legislator_x_Agency, cluster ="Legislator", data = dcounts_tenure)if(testing){modelsummary::modelsummary(m_logcon_dnd)}coefplot(m_logcon_dnd, horiz = T)
Table @tbl-models_policy is identical to Table @tbl-models_total except that we subset the data to only legislator requests hand-coded as policy work. Column 2 of Table @tbl-models_policy provides the estimated effects from the difference-in-differences specification in Equation @eq-diff1. Across all measures of institutional power, we find that more power increases the level of policy work that legislators provide. Consider first the effect of being a committee chair. We estimate that becoming a committee chair causes an increase of 0.17 policy requests per agency (95-percent confidence interval [0.1, 0.25]). Across all 92 agencies, this represents an increase of approximately 16 additional requests per year, 94% of the average requests per year in our data. There is a smaller increase for individuals who become ranking members and those who join a Prestige Committee, though the increase is statistically significant for the prestige committee. Becoming a ranking member of a committee causes an increase of 0.1 contacts per agency, while joining a prestige committee causes a 0.17 per agency increase in the policy requests a member of Congress makes.
@tab-models_total_con shows the effects of institutional power and experience on overall requests to federal agencies (Models 1 and 1) and constituency service requests (Models 3 and 4). Models 3 and 4 are identical to models 1 and 2 except that we subset the data to only legislator requests hand-coded as constituency service. Columns 2 and 4 of @tab-models_total_con provide the estimated effects from the difference-in-differences specification in @eq-diff1. More experience and receiving a committee chairship increases the total requests to federal agencies. More experience increases the level of constituency service that legislators provide. The effect of being a committee chair is positive but not significant at the .05 level.
Becoming a committee chair causes an increase of 0.25 requests per agency (95-percent confidence interval [0.07, 0.43]). Across all 92 agencies, this represents an increase of approximately 22.91 additional requests per year, 29% of the average requests per year in our data.
Subsetting to requests hand-coded as constituency service, we estimate that becoming a committee chair causes an increase of 0.02 requests per agency, but this increase is not significant at the .05 level (95-percent confidence interval [-0.1, 0.14]). Across all 92 agencies, this represents an increase of approximately 1.75 additional requests per year, 24% of the average constituency service requests per year in our data.
We estimate that the experience gained between the first and second year in Congress causes an increase of 0.09 requests per agency.
The experience gained between the first and seventh year causes an increase of 0.49 per agency. Across all 92 agencies, this represents an increase of approximately 45 additional requests per year, 35% of the average requests per year in our data. There is a smaller increase after the second year. The experience gained between the second and seventh year causes an increase of 0.4 per agency, an increase of approximately 36 additional requests per year, 29% of the average requests per year in our data.
Subsetting to requests hand-coded as constituency service, we estimate that the experience gained between the first and second year in Congress causes an increase of 0.02 constituency service requests per agency.
The experience gained between the first and seventh year causes an increase of 0.25 per agency. Across all 92 agencies, this represents an increase of approximately 23 additional constituency service requests per year, 18% of the average constituency service requests per year in our data. Again, there is a smaller increase after the second year. The experience gained between the second and seventh year causes an increase of 0.24 per agency, an increase of approximately 22 additional constituency service requests per year, 17% of the average requests per year in our data.
Model Results: Ratio
Member-level Ratio Coefficient Plots
Figures: figs/m-ratio-[1:2].png
Code
dcounts_ratio %<>%mutate(Legislator = icpsr,Year = year) %>%filter(year >2006& year <2019)m_ratio_cross <-feglm(ratio ~ chair + ranking_minority + prestige + majority + presidents_party + first + second + third + fourth + fifth + sixth | Year,cluster ="Legislator",data = dcounts_ratio)if(testing){modelsummary::modelsummary(m_ratio_cross)}coefplot(m_ratio_cross, horiz = T, drop ="(Intercept)") # Diff in diffm_ratio_dnd <-feglm(ratio ~ chair + ranking_minority + prestige + majority + presidents_party + first + second + third + fourth + fifth + sixth | Legislator + Year,cluster ="Legislator",data = dcounts_ratio)if(testing){modelsummary::modelsummary(m_ratio_dnd)}coefplot(m_ratio_dnd, horiz = T)
1
2
figs/m-ratio-[1:4].png
Ratio Table
Models: tables/models_ratio.Rdata
Code
models_ratio <-list("(1)"= m_ratio_cross,"(2)"= m_ratio_dnd)rows <-tibble(term =c("Dependent variable", "Majority", "President's party"),`(1)`=c("Ratio", "✓", "✓"),`(2)`=c("Ratio", "✓", "✓"))# all coefrows <-tibble(term =c("Dependent variable"),`(1)`=c("Ratio"),`(2)`=c("Ratio"))# Check marks for controls attr(rows, 'position') <-c(0, 20,21)# all coefattr(rows, 'position') <-c(0)modelsummary(models_ratio,notes =list("Robust standard errors in parentheses, clustered by legislator.") )
(1)
(2)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by legislator.
Column 2 of Table @tbl-models_ratio provides the estimated effects from the difference-in-differences specification. We estimate that becoming a committee chair causes the ratio of constituency service to policy work to decrease by 0.08 (95-percent confidence interval [-0.05, -0.12 ]). Becoming a ranking member of a committee causes a decrease of 0.04 in the ratio.
Predictions
Results in manuscript (Figure 7, p. 41)
Figures: figs/m-ratio-predicted-[1:4].png
Code
predicted <-predictions(m_ratio_cross,newdata = values)# Cross-sectional predictionspredicted %>%ggchair() +labs(#title = "", # Predicted ratio of constituent to policy work\n(cross-sectional)",x ="",y ="Predicted ratio of\nconstituent to policy work",fill ="",color ="",shape ="")# by tenurepredicted <-predictions(m_ratio_cross,newdata = values_tenure)predicted %>%ggtenure() +labs(#title = "", # "Predicted Ratio of Constituent to Policy Work\n(cross-sectional)",x ="Years serving in Congress",y ="Predicted ratio of\nconstituent to policy work",fill ="",color ="",shape ="")# Predictions for diff in diff plot predicted <-predictions(m_ratio_dnd,newdata = values)# diff in diff plotpredicted %>%ggchair() +labs(#title = "", # "Predicted Ratio of Constituent to Policy Work\nDifference in Differences (Within-Legislator)",x ="",y ="Predicted ratio of\nconstituent to policy work",fill ="",color ="",shape ="")# by tenurepredicted <-predictions(m_ratio_dnd,newdata = values_tenure)predicted %>%ggtenure() +geom_line(aes(x =as.numeric(year_in_congress %>%str_sub(1,1)))) +labs(#title = "", # "Predicted Ratio of Constituent to Policy Work\nDifference in Differences (Within-Legislator)",x ="Years serving in Congress",y ="Predicted ratio of\nconstituent to policy work",fill ="",color ="",shape ="")
1
2
3
4
m-ratio-predicted
Model Results: Per District
Data
The main district-level models in the paper focus on estimating the effect of legislator experience by leveraging turnover within districts. We compare the service that a district receives before and after electing a new legislator and in the following years as legislators gain experience in office.
Same party lookup table
As a robustness check, we replicate our within-district results using a subset of district-year-count observations where turnover in a district allows us to assess the partisanship of the prior member holding that seat. We interact an indicator of whether the prior member was of the same party with all other indicators (i.e., whether the member is new, serving in years 1-6, or serving longer than 6 years). We compare the service that a district receives before and after electing a new legislator and, in the following years, accounting for whether that member is of the same party. However, a structural constraint of the data means that this robustness check is limited to observations where turnover within a redistricting cycle gives us a measure of whether the legislator replaced a member of the same party or of another party.
The table below accounts for redistricting by treating post-redistricting districts as new entities, not the same district as the one with the same number prior to redistricting (i.e., we do NOT count cases where a district elects someone of the same or different party as the district with the same number had before redistricting). Since some states completely re-number their districts, there is no way to be sure that a new District 4 has any relationship to the District 4 under the previous redistricting map (though it often may have significant overlap) without creating some spatial measure of the percent of shared census tracts, or something like that, which we do not attempt.
Many NAs exist for the same party variable because we only observe it when there is turnover within a redistricting cycle. Seats that do not turn over for an entire cycle (e.g., 2002-2012) are FALSE (“0”) for “new member” and have no value for “same party.” Other districts are NA until there is turnover. Thus, adding “same party” causes significant data loss due to NAs.
Warning
Specifically, we go from 7666 to 2822 observations when including same_party in the models below.
These observations are not missing at random, so all models with the same_party variable should be interpreted with great caution.
To measure turnover in the Senate where “districts” have two members, we code same party as FALSE if there is a change in the partisanship of a state’s Senate delegation. This captures the parallel dynamic of single-member House districts. If there are two Democrats and one is replaced by a Republican, the same party is FALSE. If there are two Democrats and a Democrat is elected, the same party is TRUE. If there are a Democrat senator and a Republican senator representing a state, and the Democrat is replaced by a Republican, same_party is FALSE. As per the VoteView convention, Senate delegations are District “0” (e.g., “alabama_0”). Split Senate delegations appear as “Democratic Party;Republican Party” in the table below.
Code
# year congress crosswalk year_congress <- dcounts_tenure %>%distinct(year, congress)# Add Congress variable dcounts_per_district %<>%ungroup() %>%# Add Congress variable left_join(year_congress)member_data %<>%left_join(year_congress) %>%arrange(icpsr, year)duplicates <-distinct(dcounts_per_district, icpsr, chamber, congress, state, state_dist, new_member) %>%count(icpsr, chamber, congress, state_dist) %>%filter(n >1) # Because members of the house are new one year and not the other, we can't do "new" at the Congress level # inner_join(duplicates, dcounts_per_district)# make a variable for the prior seat holder party party_crosswalk <- member_data %>%ungroup() %>%# add new member and state_dist (accounting for redistricting)left_join(distinct(dcounts_per_district, icpsr, chamber, congress, state, state_dist, new_member, year)) %>%# Begin at 2000 census redistricting filter(year >2001) %>%# Make additional new member and state_dist to fill in NAs with "0" (i.e., 2002-2012 redistricting cycle )mutate(state_dist2 =paste(state, district_code, "0", sep ="_") |>str_replace("0_0", "0"),state_dist =coalesce(state_dist, state_dist2)) %>%group_by(state_dist, chamber, year) %>%# combine ICPSR IDS for senators to get the senate delegation to know if it changed arrange(icpsr) |># Make sure they are in the same order mutate(icpsr =unique(icpsr) |>paste(collapse =";")) %>%# collapse senate ICPSRungroup() %>%group_by(state_dist, chamber) |>arrange(year) |>mutate(lag_icpsr = dplyr::lag(icpsr),new_member2 = icpsr != lag_icpsr,new_member =coalesce(new_member, as.numeric(new_member2))) %>%distinct(year, congress, state_dist, state, district_code, party, new_member #, new_member2, icpsr, lag_icpsr ) %>%#FIXME DROPPING OBS HERE# # for Senate, capture mixed delegations group_by(state_dist, year) %>%arrange(party) %>%mutate(state_dist_party =unique(party) |>paste(collapse =";")) %>%ungroup() %>%# state_dist is missing for some obs in member_data, so here is a backup that does not account for redistricting. If we end up needing this, we should correct it to the districts accounting for redistrictingmutate(state_dist2 =paste(state, district_code, sep ="_")) %>%distinct(congress, state_dist, state_dist_party, new_member, year #, new_member2, icpsr, lag_icpsr ) %>%arrange(state_dist, year) %>%# group by icpsr group_by(state_dist) %>%# create lag party var and fill it in for that member's tenure mutate(lag_p = dplyr::lag(state_dist_party), same_party = state_dist_party == lag_p,same_party =ifelse(new_member, same_party,NA )) %>% tidyr::fill(same_party, .direction ="down") %>%ungroup()# LOOK FOR MISSING OBS BY CONGRESS #member_data |> count(congress)#party_crosswalk |> ungroup() |> count(congress, is.na(state_dist))#party_crosswalk |> ungroup() |> filter(is.na(state_dist), congress > 109)party_crosswalk |>select(year, state_dist, state_dist_party, lag_p, same_party, new_member) |>kablebox_long()
year
state_dist
state_dist_party
lag_p
same_party
new_member
2009
NA_0
(D)
NA
NA
NA
2010
NA_0
(D)
(D)
NA
0
2019
NA_0
(D);(R)
(D)
NA
0
2019
NA_0
(D);(R)
(D);(R)
TRUE
1
2020
NA_0
(D);(R)
(D);(R)
TRUE
0
2007
NA_1_0
(D)
NA
NA
NA
2007
NA_1_0
(D)
(D)
NA
0
2008
NA_1_0
(D)
(D)
NA
0
2009
NA_1_0
(D);(I)
(D)
FALSE
1
2009
NA_1_0
(D);(I)
(D);(I)
FALSE
0
2010
NA_1_0
(D);(I)
(D);(I)
FALSE
0
2019
NA_1_0
(D)
(D);(I)
FALSE
1
2020
NA_1_0
(D)
(D)
FALSE
0
2007
alabama_0
(R)
NA
NA
0
2008
alabama_0
(R)
(R)
NA
0
2009
alabama_0
(R)
(R)
NA
0
2010
alabama_0
(R)
(R)
NA
0
2011
alabama_0
(R)
(R)
NA
0
2012
alabama_0
(R)
(R)
NA
0
2013
alabama_0
(R)
(R)
NA
0
2014
alabama_0
(R)
(R)
NA
0
2015
alabama_0
(R)
(R)
NA
0
2016
alabama_0
(R)
(R)
NA
0
2017
alabama_0
(D);(R)
(R)
FALSE
1
2017
alabama_0
(D);(R)
(D);(R)
FALSE
0
2018
alabama_0
(D);(R)
(D);(R)
FALSE
0
2019
alabama_0
(D);(R)
(D);(R)
FALSE
0
2020
alabama_0
(D);(R)
(D);(R)
FALSE
0
2007
alabama_1_0
(R)
NA
NA
0
2008
alabama_1_0
(R)
(R)
NA
0
2009
alabama_1_0
(R)
(R)
NA
0
2010
alabama_1_0
(R)
(R)
NA
0
2011
alabama_1_1
(R)
NA
NA
0
2012
alabama_1_1
(R)
(R)
NA
0
2013
alabama_1_1
(R)
(R)
NA
0
2013
alabama_1_1
(R)
(R)
TRUE
1
2014
alabama_1_1
(R)
(R)
TRUE
0
2015
alabama_1_1
(R)
(R)
TRUE
0
2016
alabama_1_1
(R)
(R)
TRUE
0
2017
alabama_1_1
(R)
(R)
TRUE
0
2018
alabama_1_1
(R)
(R)
TRUE
0
2019
alabama_1_1
(R)
(R)
TRUE
0
2020
alabama_1_1
(R)
(R)
TRUE
0
2007
alabama_2_0
(R)
NA
NA
0
2008
alabama_2_0
(R)
(R)
NA
0
2009
alabama_2_0
(D)
(R)
FALSE
1
2010
alabama_2_0
(D)
(D)
FALSE
0
2011
alabama_2_1
(R)
NA
NA
1
2012
alabama_2_1
(R)
(R)
NA
0
2013
alabama_2_1
(R)
(R)
NA
0
2014
alabama_2_1
(R)
(R)
NA
0
2015
alabama_2_1
(R)
(R)
NA
0
2016
alabama_2_1
(R)
(R)
NA
0
2017
alabama_2_1
(R)
(R)
NA
0
2018
alabama_2_1
(R)
(R)
NA
0
2019
alabama_2_1
(R)
(R)
NA
0
2020
alabama_2_1
(R)
(R)
NA
0
2007
alabama_3_0
(R)
NA
NA
0
2008
alabama_3_0
(R)
(R)
NA
0
2009
alabama_3_0
(R)
(R)
NA
0
2010
alabama_3_0
(R)
(R)
NA
0
2011
alabama_3_1
(R)
NA
NA
0
2012
alabama_3_1
(R)
(R)
NA
0
2013
alabama_3_1
(R)
(R)
NA
0
2014
alabama_3_1
(R)
(R)
NA
0
2015
alabama_3_1
(R)
(R)
NA
0
2016
alabama_3_1
(R)
(R)
NA
0
2017
alabama_3_1
(R)
(R)
NA
0
2018
alabama_3_1
(R)
(R)
NA
0
2019
alabama_3_1
(R)
(R)
NA
0
2020
alabama_3_1
(R)
(R)
NA
0
2007
alabama_4_0
(R)
NA
NA
0
2008
alabama_4_0
(R)
(R)
NA
0
2009
alabama_4_0
(R)
(R)
NA
0
2010
alabama_4_0
(R)
(R)
NA
0
2011
alabama_4_1
(R)
NA
NA
0
2012
alabama_4_1
(R)
(R)
NA
0
2013
alabama_4_1
(R)
(R)
NA
0
2014
alabama_4_1
(R)
(R)
NA
0
2015
alabama_4_1
(R)
(R)
NA
0
2016
alabama_4_1
(R)
(R)
NA
0
2017
alabama_4_1
(R)
(R)
NA
0
2018
alabama_4_1
(R)
(R)
NA
0
2019
alabama_4_1
(R)
(R)
NA
0
2020
alabama_4_1
(R)
(R)
NA
0
2007
alabama_5_0
(D)
NA
NA
0
2008
alabama_5_0
(D)
(D)
NA
0
2009
alabama_5_0
(D);(R)
(D)
FALSE
1
2010
alabama_5_0
(D);(R)
(D);(R)
FALSE
0
2011
alabama_5_1
(R)
NA
NA
1
2012
alabama_5_1
(R)
(R)
NA
0
2013
alabama_5_1
(R)
(R)
NA
0
2014
alabama_5_1
(R)
(R)
NA
0
2015
alabama_5_1
(R)
(R)
NA
0
2016
alabama_5_1
(R)
(R)
NA
0
2017
alabama_5_1
(R)
(R)
NA
0
2018
alabama_5_1
(R)
(R)
NA
0
2019
alabama_5_1
(R)
(R)
NA
0
2020
alabama_5_1
(R)
(R)
NA
0
2007
alabama_6_0
(R)
NA
NA
0
Code
# Add same_party variable to district counts data dcounts_per_district %<>%left_join(party_crosswalk ) %>%arrange(state_dist, congress) %>%ungroup()dcounts_per_district |>count(same_party) |>kablebox()
The main results showing that replacing a more experienced legislator with a new legislator yields a substantial decrease in service to the district are robust to interacting all variables with the same_party variable. Cross-sectional effects get larger but more uncertain when data are subset to district years after turnover (as required for the same_party variable). Within-district effects become more uncertain, likely due to the much smaller number of observations where same_party can be observed.
Total District-level Coefficient Plots
Figures: figs/m-district-[1:4].png
cross-sectional
cross-sectional with same-party variable
diff-in-diff
diff-in-diff with same party variable
Code
# modify var names for presentation dcounts_per_district %<>%mutate(same_party =as.numeric(same_party),Legislator = icpsr,District = state_dist,Year = year)m_district_cross <-feglm(perYear ~ new_member + second + third + fourth + fifth + sixth | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_cross)}coefplot(m_district_cross, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") m_district_cross_party <-feglm(perYear ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_cross)}coefplot(m_district_cross_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_dnd <-feglm(perYear ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_dnd, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_dnd_party <-feglm(perYear ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_dnd_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_dnd_house <-feglm(perYear ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diff + party change var m_district_dnd_house_party <-feglm(perYear ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diffm_district_dnd_senate <-feglm(perYear ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))# Diff in diff + party change var m_district_dnd_senate_party <-feglm(perYear ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))
1
2
3
4
figs/m-district-[1:4].png
Total Per District Tables
Models: models/models_district.Rdata
Code
models_district <-list("(1)"= m_district_cross,"(2)"= m_district_dnd,"(3)"= m_district_dnd_house,"(4)"= m_district_dnd_senate)rows <-tibble(term =c("Dependent variable", "All districts","House only","Senate only"),`(1)`=c("Per year", "✓", "", ""),`(2)`=c("Per year", "✓", "", ""),`(3)`=c("Per year", "", "✓", ""),`(4)`=c("Per year", #"✓", "", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 14:16)modelsummary(models_district,notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
models_district_party <-list("(1)"= m_district_cross_party,"(2)"= m_district_dnd_party,"(3)"= m_district_dnd_house_party,"(4)"= m_district_dnd_senate_party)# Check marks for controls attr(rows, 'position') <-c(0, 28:31)modelsummary(models_district_party, notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year
Per year
Per year
Per year
New member
-29.636*
-23.178*
-5.726
-59.353*
(12.715)
(11.591)
(13.975)
(24.403)
New member x same party
-50.373**
-23.779†
12.661
-74.273*
(18.089)
(13.729)
(9.430)
(31.816)
Second year
-46.808**
-45.709**
-2.477
-88.831**
(13.908)
(12.498)
(11.333)
(30.589)
Third year
-18.336
-8.392
-0.818
-0.411
(12.896)
(12.174)
(13.041)
(30.666)
Fourth year
-44.929*
-42.147*
-0.493
4.518
(20.686)
(18.377)
(17.162)
(30.076)
Fifth year
-13.885
-10.366
-15.299
17.073
(11.301)
(12.583)
(11.054)
(31.988)
Sixth year
-21.885
-27.370
-1.759
130.998
(31.805)
(35.706)
(24.924)
(169.982)
Second year x same party
-33.944†
-9.583
22.054*
0.401
(17.711)
(15.329)
(10.953)
(39.652)
Third year x same party
-28.534
-4.330
21.610*
-53.187
(17.892)
(15.188)
(9.678)
(39.246)
Fourth year x same party
-3.978
17.093
36.267*
-42.671
(24.630)
(20.148)
(17.304)
(38.065)
Fifth year x same party
-22.848
-3.375
24.389*
-55.532
(16.859)
(15.631)
(9.659)
(34.705)
Sixth year x same party
-6.799
12.608
37.033
-145.917
(36.816)
(40.529)
(32.902)
(171.269)
Same party
33.793†
-7.052
-18.174
27.238
(18.234)
(14.041)
(14.297)
(21.801)
All districts
✓
✓
House only
✓
Senate only
✓
Observations
2,222
2,222
1,523
699
District fixed effects
X
X
X
Year fixed effects
X
X
X
X
Code
save(models_district_party, rows, cm, gm, beta, se,file = here::here("models", "models_district_party.Rdata"))
To account for differences in district size, demographics, and demand for constituency service, Column 2 of Table @tbl-models_district provides the estimated effects from the difference-in-differences specification from Equation @eq-district1. In this specification, we see a large causal effect of a new member taking over: Electing a new member causes a district’s constituency service to decrease by about 40%, or 24.57 letters per year (95-percent confidence interval [-15.59, -33.55 ]).
The effect of electing a new representative, however, dissipates quickly. Districts represented by a legislator in their second year of service receive significantly fewer contacts with federal agencies, but not as drastic as the difference observed in the first year. After the second year, the differences are smaller. This phenomenon–new legislators providing substantially fewer requests–persists when examining the House (Column 3) and the Senate (Column 4) separately. In short, new legislators make fewer contacts for their constituents than established legislators.
Total Per District Predictions
Results in manuscript (Figure 6, p. 38)
Figures: figs/m-district-predicted-[1:4].png
Code
ggdistrict <-function(predicted = predicted, party =FALSE) {predicted %<>%# drop estimates from impossible valuesgroup_by(rowid, #predicted, std.error, estimate, conf.low, conf.high, same_party) %>%mutate(sum =sum(new_member, second, third, fourth, fifth, sixth),more =ifelse(sum ==0, 1,0)) %>%filter(sum <2) %>%pivot_longer(cols =c("new_member", "second", "third", "fourth", "fifth", "sixth", "more")) %>%select(name, value) %>%filter(value ==1) %>%# clean up for presentationmutate(year_in_congress = name %>%str_replace("more", "7\nor more") %>%str_replace("sixth", "6") %>%str_replace("fifth", "5") %>%str_replace("fourth", "4") %>%str_replace("third", "3") %>%str_replace("second", "2") %>%str_replace("new_member", " New\nmember") ) %>%ungroup()# Ideally, we could plot against data, but there is so much variation that you can no longer distinguish differences in predicted values # predicted %<>% full_join(dcounts_tenure2 %>% mutate(predicted = NA))p <- predicted %>%ungroup() %>%ggplot() +aes(x = year_in_congress, y = estimate, # predicted, ymin = conf.low,# predicted - 1.96*std.error,ymax = conf.high) +geom_pointrange(position =position_dodge(width =-.3) ) +# geom_line() + # requires numeric...look to see how I did this on the other onesscale_fill_viridis_d(begin =0, end = .6, option ="cividis") +scale_color_viridis_d(begin =0, end = .6, option ="cividis") if(party){p <- predicted %>%mutate(same_party =as.logical(same_party)) %>%ungroup() %>%ggplot() +aes(x = year_in_congress, y = estimate, # predicted, ymin = conf.low,# predicted - 1.96*std.error,ymax = conf.high, #predicted + 1.96*std.error,shape = same_party,color = same_party) +geom_pointrange(position =position_dodge(width =-.3) ) +scale_fill_viridis_d(begin =0, end = .6, option ="cividis") +scale_color_viridis_d(begin =0, end = .6, option ="cividis") }return(p)}# dcounts_per_district %>% filter(District == "tennessee_1_1") |> View()# dcounts_per_district %>% filter(District == "alabama_1_1") |> View()# by year values <- tidyr::expand(dcounts_per_district,new_member = new_member,second = second,third = third,fourth = fourth,fifth = fifth, sixth = sixth,Legislator ="21376",Year ="2016",District ="alabama_1_1",same_party = same_party ) %>%drop_na(same_party)predicted <-predictions(m_district_cross,newdata = values) # Cross-sectional predictionspredicted %>%ggdistrict() +labs(#title = "Letters\nper district\n(cross-sectional)",x ="Years serving in Congress",y =" Predicted letters\nper year per district\n(cross-sectional)",fill ="",color ="",shape ="") # Predictions with the party of the prior representativepredicted <-predictions(m_district_cross_party,newdata = values) predicted %>%ggdistrict(party =TRUE) +labs(# title = "",x ="Years serving in Congress",y =" Predicted letters\nper year per district\n(cross-sectional)",fill ="",color ="Same party",shape ="Same party") # diff in diff plotpredicted <-predictions(m_district_dnd,newdata = values) predicted %>%ggdistrict() +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters\nper district\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters\nper year per district\n(difference-in-differneces)",fill ="",color ="",shape ="")# Predictions with the Same party predicted <-predictions(m_district_dnd_party,newdata = values) # diff in diff plotpredicted %>%ggdistrict(party =TRUE) +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters Per District\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters\nper year per district\n(difference-in-differences)",fill ="",color ="Same party",shape ="Same party")
# Values for Senate seats values <- tidyr::expand(dcounts_per_district,new_member = new_member,second = second,third = third,fourth = fourth,fifth = fifth, sixth = sixth,Legislator ="49700",Year ="2017",District ="alabama_0",same_party = same_party ) %>%drop_na(same_party)# diff in diff plotpredicted <-predictions(m_district_dnd_senate,newdata = values) predicted %>%ggdistrict() +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\nper Senator\n(difference-in-differneces)",fill ="",color ="",shape ="")# Predictions with the Same party predicted <-predictions(m_district_dnd_senate_party,newdata = values) # diff in diff plotpredicted %>%ggdistrict(party =TRUE) +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\nper Senator\n(difference-in-differences)",fill ="",color ="Same party",shape ="Same party")
1
2
figs/m-district-predicted-senate-[1:2].png
Constituency Service Letters per District
The main results showing that replacing a more experienced legislator with a new legislator yields a substantial decrease in service to the district are robust to interacting all variables with the same_party variable. Cross-sectional effects get larger but more uncertain when data are subset to district years after turnover (as required for the same_party variable). Within-district effects become more uncertain, likely due to the much smaller number of observations where same_party can be observed.
Constituency Service District-level Coefficient Plots
Figures: figs/m-district-con-[1:4].png
cross-sectional
cross-sectional with same-party variable
diff-in-diff
diff-in-diff with same party variable
Code
m_district_con_cross <-feglm(perYear_con ~ new_member + second + third + fourth + fifth + sixth | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_con_cross)}coefplot(m_district_con_cross, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") m_district_con_cross_party <-feglm(perYear_con ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_con_cross)}coefplot(m_district_con_cross_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_con_dnd <-feglm(perYear_con ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_con_dnd, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_con_dnd_party <-feglm(perYear_con ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_con_dnd_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_con_dnd_house <-feglm(perYear_con ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diff + party change var m_district_con_dnd_house_party <-feglm(perYear_con ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diffm_district_con_dnd_senate <-feglm(perYear_con ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))# Diff in diff + party change var m_district_con_dnd_senate_party <-feglm(perYear_con ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))
1
2
3
4
figs/m-district-con-[1:4].png
Constituency Service Per District Tables
Models: models/models_district_con.Rdata
Code
models_district_con <-list("(1)"= m_district_con_cross,"(2)"= m_district_con_dnd,"(3)"= m_district_con_dnd_house,"(4)"= m_district_con_dnd_senate)rows <-tibble(term =c("Dependent variable", "All districts","House only","Senate only"),`(1)`=c("Per year", "✓", "", ""),`(2)`=c("Per year", "✓", "", ""),`(3)`=c("Per year", "", "✓", ""),`(4)`=c("Per year", "", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 14:16)modelsummary(models_district_con, notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
models_district_con_party <-list("(1)"= m_district_con_cross_party,"(2)"= m_district_con_dnd_party,"(3)"= m_district_con_dnd_house_party,"(4)"= m_district_con_dnd_senate_party)# Check marks for controls attr(rows, 'position') <-c(0, 28:31)modelsummary(models_district_con_party, notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year
Per year
Per year
Per year
New member
-8.519
-1.835
-4.479
-20.841
(9.301)
(11.062)
(12.858)
(22.389)
New member x same party
-40.031**
-14.008
15.526†
-59.484*
(14.216)
(11.964)
(8.516)
(28.259)
Second year
-30.639**
-29.618*
-6.171
-66.226†
(9.894)
(11.514)
(10.272)
(36.671)
Third year
-1.819
6.611
-0.618
8.357
(9.763)
(11.342)
(12.004)
(26.818)
Fourth year
-31.456†
-30.140†
-1.973
9.787
(18.622)
(17.442)
(16.693)
(25.149)
Fifth year
-4.299
-5.202
-15.185
1.214
(8.872)
(10.452)
(9.226)
(22.160)
Sixth year
-18.366
-27.845
-4.419
124.006
(31.481)
(35.139)
(24.402)
(166.703)
Second year x same party
-27.758†
-3.579
23.106*
17.351
(14.406)
(14.053)
(9.896)
(42.914)
Third year x same party
-22.546
0.296
21.710*
-29.673
(14.324)
(13.353)
(8.794)
(34.640)
Fourth year x same party
-3.762
16.820
33.780*
-28.509
(21.815)
(18.457)
(16.874)
(31.529)
Fifth year x same party
-16.480
3.085
25.572**
-22.196
(13.490)
(12.459)
(7.641)
(24.587)
Sixth year x same party
-1.686
18.238
37.244
-125.666
(35.622)
(39.215)
(32.622)
(167.604)
Same party
27.264†
-7.737
-20.902
20.086
(14.139)
(12.325)
(13.050)
(19.725)
All districts
✓
✓
House only
✓
Senate only
✓
Observations
2,222
2,222
1,523
699
District fixed effects
X
X
X
Year fixed effects
X
X
X
X
Code
save(models_district_con_party, rows, cm, gm, beta, se,file = here::here("models", "models_district_con_party.Rdata"))
Constituency Service Per District Narrative
To account for differences in district size, demographics, and demand for constituency service, Column 2 of Table @tbl-models_district_con provides the estimated effects from the difference-in-differences specification from Equation @eq-district1. In this specification, we see a large causal effect of a new member taking over: Electing a new member causes a district’s constituency service to decrease by 10.95 letters per year (95-percent confidence interval [-4.1, -17.79 ]).
The effect of electing a new representative, however, dissipates quickly. Districts represented by a legislator in their second year of service receive significantly fewer contacts with federal agencies, but not as drastic as the difference observed in the first year. After the second year, the differences are smaller. This phenomenon–new legislators providing substantially fewer requests–persists when examining the Senate (Column 4) separately. When examining the House separately, the pattern is similar but slightly different; members make few constituency service requests in their first two years before increasing to a higher level in years 3-6 and then possibly decreasing after that (since seven or more years in office is the reference category, we don’t have uncertainty bounds around this estimate). In short, new legislators make fewer contacts for their constituents than established legislators.
Constituency Service Per District Predictions
Figures: figs/m-district-con-predicted-[1:4].png
Code
ggdistrict <-function(predicted = predicted, party =FALSE) {predicted %<>%# drop estimates from impossible valuesgroup_by(rowid, #predicted, std.error, estimate, conf.low, conf.high, same_party) %>%mutate(sum =sum(new_member, second, third, fourth, fifth, sixth),more =ifelse(sum ==0, 1,0)) %>%filter(sum <2) %>%pivot_longer(cols =c("new_member", "second", "third", "fourth", "fifth", "sixth", "more")) %>%select(name, value) %>%filter(value ==1) %>%# clean up for presentationmutate(year_in_congress = name %>%str_replace("more", "7\nor more") %>%str_replace("sixth", "6") %>%str_replace("fifth", "5") %>%str_replace("fourth", "4") %>%str_replace("third", "3") %>%str_replace("second", "2") %>%str_replace("new_member", " New\nmember") ) %>%ungroup()# Ideally, we could plot against data, but there is so much variation that you can no longer distinguish differences in predicted values # predicted %<>% full_join(dcounts_tenure2 %>% mutate(predicted = NA))p <- predicted %>%ungroup() %>%ggplot() +aes(x = year_in_congress, y = estimate, # predicted, ymin = conf.low,# predicted - 1.96*std.error,ymax = conf.high) +geom_pointrange(position =position_dodge(width =-.3) ) +# geom_line() + # requires numeric...look to see how I did this on the other onesscale_fill_viridis_d(begin =0, end = .6, option ="cividis") +scale_color_viridis_d(begin =0, end = .6, option ="cividis") if(party){p <- predicted %>%mutate(same_party =as.logical(same_party)) %>%ungroup() %>%ggplot() +aes(x = year_in_congress, y = estimate, # predicted, ymin = conf.low,# predicted - 1.96*std.error,ymax = conf.high, #predicted + 1.96*std.error,shape = same_party,color = same_party) +geom_pointrange(position =position_dodge(width =-.3) ) +scale_fill_viridis_d(begin =0, end = .6, option ="cividis") +scale_color_viridis_d(begin =0, end = .6, option ="cividis") }return(p)}# dcounts_per_district %>% filter(District == "tennessee_1_1") |> View()# dcounts_per_district %>% filter(District == "alabama_1_1") |> View()# by year values <- tidyr::expand(dcounts_per_district,new_member = new_member,second = second,third = third,fourth = fourth,fifth = fifth, sixth = sixth,Legislator ="21376",Year ="2016",District ="alabama_1_1",same_party = same_party ) %>%drop_na(same_party)predicted <-predictions(m_district_con_cross,newdata = values) # Cross-sectional predictionspredicted %>%ggdistrict() +labs(#title = "Letters\nper district\n(cross-sectional)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper district\n(cross-sectional)",fill ="",color ="",shape ="") # Predictions with the party of the prior representativepredicted <-predictions(m_district_con_cross_party,newdata = values) predicted %>%ggdistrict(party =TRUE) +labs(#title = "Letters\nper district\n(cross-sectional)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper district\n(cross-sectional)",fill ="",color ="Same party",shape ="Same party") # diff in diff plotpredicted <-predictions(m_district_con_dnd,newdata = values) predicted %>%ggdistrict() +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters\nper district\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper district\n(difference-in-differneces)",fill ="",color ="",shape ="")# Predictions with the Same party predicted <-predictions(m_district_con_dnd_party,newdata = values) # diff in diff plotpredicted %>%ggdistrict(party =TRUE) +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters Per District\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper district\n(difference-in-differences)",fill ="",color ="Same party",shape ="Same party")
1
2
3
4
figs/m-district-con-predicted-[1:4].png
Constituency Service Per District Predictions (House only)
# Values for Senate seats values <- tidyr::expand(dcounts_per_district,new_member = new_member,second = second,third = third,fourth = fourth,fifth = fifth, sixth = sixth,Legislator ="49700",Year ="2017",District ="alabama_0",same_party = same_party ) %>%drop_na(same_party)# diff in diff plotpredicted <-predictions(m_district_con_dnd_senate,newdata = values) predicted %>%ggdistrict() +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper senator\n(difference-in-differneces)",fill ="",color ="",shape ="")# Predictions with the Same party predicted <-predictions(m_district_con_dnd_senate_party,newdata = values) # diff in diff plotpredicted %>%ggdistrict(party =TRUE) +geom_line(aes(x =as.numeric(year_in_congress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(constituency service only)\nper senator\n(difference-in-differences)",fill ="",color ="Same party",shape ="Same party")
1
2
figs/m-district-con-predicted-senate-[1:2].png
Policy Letters per District
The main results showing that replacing a more experienced legislator with a new legislator yields a substantial decrease in policy work to the district are robust to interacting all variables with the same_party variable. Cross-sectional effects get larger but more uncertain when data are subset to district years after turnover (as required for the same_party variable). Within-district effects become more uncertain, likely due to the much smaller number of observations where same_party can be observed.
Policy District-level Coefficient Plots
Figures: figs/m-district-policy-[1:4].png
cross-sectional
cross-sectional with same-party variable
diff-in-diff
diff-in-diff with Same party variable
Code
m_district_policy_cross <-feglm(perYear_policy ~ new_member + second + third + fourth + fifth + sixth | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_policy_cross)}coefplot(m_district_policy_cross, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") m_district_policy_cross_party <-feglm(perYear_policy ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | Year,cluster ="District",data = dcounts_per_district)if(testing){modelsummary::modelsummary(m_district_policy_cross)}coefplot(m_district_policy_cross_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_policy_dnd <-feglm(perYear_policy ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_policy_dnd, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_policy_dnd_party <-feglm(perYear_policy ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district )coefplot(m_district_policy_dnd_party, horiz = T, drop ="(Intercept)", sub ="Reference = A member serving >6 years") # Diff in diffm_district_policy_dnd_house <-feglm(perYear_policy ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diff + party change var m_district_policy_dnd_house_party <-feglm(perYear_policy ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="House"))# Diff in diffm_district_policy_dnd_senate <-feglm(perYear_policy ~ new_member +#same_party + second + third + fourth + fifth + sixth | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))# Diff in diff + party change var m_district_policy_dnd_senate_party <-feglm(perYear_policy ~ new_member*same_party + second*same_party + third*same_party + fourth*same_party + fifth*same_party + sixth*same_party | District + Year,cluster ="District",data = dcounts_per_district |>filter(chamber =="Senate"))
1
2
3
4
figs/m-district-policy-[1:4].png
Policy Per District Tables
Models: models/models_district_policy.Rdata
Code
models_district_policy <-list("(1)"= m_district_policy_cross,"(2)"= m_district_policy_dnd,"(3)"= m_district_policy_dnd_house,"(4)"= m_district_policy_dnd_senate)rows <-tibble(term =c("Dependent variable", "All districts","House only","Senate only"),`(1)`=c("Per year", "✓", "", ""),`(2)`=c("Per year", "✓", "", ""),`(3)`=c("Per year", "", "✓", ""),`(4)`=c("Per year", #"✓", "", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 14:16)modelsummary(models_district_policy, notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
models_district_policy_party <-list("(1)"= m_district_policy_cross_party,"(2)"= m_district_policy_dnd_party,"(3)"= m_district_policy_dnd_house_party,"(4)"= m_district_policy_dnd_senate_party)# Check marks for controls attr(rows, 'position') <-c(0, 28:31)modelsummary(models_district_policy_party, notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
(4)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year
Per year
Per year
Per year
New member
-12.772**
-12.071**
-1.542
-20.611**
(2.503)
(2.083)
(1.316)
(3.734)
New member x same party
-4.850†
-4.189*
-0.912
-5.766
(2.686)
(2.092)
(1.177)
(3.848)
Second year
-9.224**
-8.809**
1.737
-12.891*
(2.744)
(2.274)
(1.064)
(5.343)
Third year
-11.108**
-8.692**
-0.778
-5.372
(2.410)
(2.060)
(1.239)
(5.610)
Fourth year
-8.041**
-5.944**
1.526
-1.825
(2.471)
(2.231)
(0.961)
(6.108)
Fifth year
-6.584**
-2.986
-0.611
10.673
(1.924)
(2.167)
(0.960)
(10.190)
Sixth year
-1.978
1.221
2.669*
1.311
(2.613)
(2.319)
(1.312)
(10.414)
Second year x same party
-3.237
-2.710
-0.249
-6.996
(2.635)
(2.163)
(1.242)
(5.312)
Third year x same party
-2.214
-2.384
0.510
-13.233*
(2.637)
(2.351)
(1.262)
(6.031)
Fourth year x same party
-0.141
-0.619
1.327
-11.165†
(2.416)
(2.372)
(1.181)
(6.260)
Fifth year x same party
-3.510
-4.411
-0.562
-22.230*
(2.365)
(2.773)
(1.070)
(10.544)
Sixth year x same party
-2.488
-3.328
-0.950
-7.539
(2.981)
(2.755)
(1.531)
(10.532)
Same party
2.926
-0.489
0.495
3.026
(2.738)
(2.788)
(1.390)
(3.333)
All districts
✓
✓
House only
✓
Senate only
✓
Observations
2,222
2,222
1,523
699
District fixed effects
X
X
X
Year fixed effects
X
X
X
X
Code
save(models_district_policy_party, rows, cm, gm, beta, se,file = here::here("models", "models_district_policy_party.Rdata"))
Policy Per District Narrative
To account for differences in district size, demographics, and demand for Policy, Column 2 of Table @tbl-models_district_policy provides the estimated effects from the difference-in-differences specification from Equation @eq-district1. In this specification, we see a large causal effect of a new member taking over: Electing a new member causes a district’s Policy to decrease by 7.25 letters per year (95-percent confidence interval [-5.85, -8.65 ]).
The effect of electing a new representative, however, dissipates quickly. Districts represented by a legislator in their second year of service receive significantly fewer policy-related contacts with federal agencies, but not as drastic as the difference observed in the first year. After the second year, the differences are smaller. This phenomenon–new legislators providing substantially fewer requests–persists when examining the House (Column 3) and the Senate (Column 4) separately. In short, new legislators make fewer policy-related contacts than established legislators.
# Values for Senate seats values <- tidyr::expand(dcounts_per_district,new_member = new_member,second = second,third = third,fourth = fourth,fifth = fifth, sixth = sixth,Legislator ="49700",Year ="2017",District ="alabama_0",same_party = same_party ) %>%drop_na(same_party)# diff in diff plotpredicted <-predictions(m_district_policy_dnd_senate,newdata = values) predicted %>%ggdistrict() +geom_line(aes(x =as.numeric(year_in_policygress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(policy only)\nper senator\n(difference-in-differneces)",fill ="",color ="",shape ="")# Predictions with the Same party predicted <-predictions(m_district_policy_dnd_senate_party,newdata = values) # diff in diff plotpredicted %>%ggdistrict(party =TRUE) +geom_line(aes(x =as.numeric(year_in_policygress %>%str_replace(" N", "1") %>%str_sub(1,1) ))) +labs(#title = "Letters per senator\n(difference-in-differences)",x ="Years serving in Congress",y =" Predicted letters per year\n(policy only)\nper senator\n(difference-in-differences)",fill ="",color ="Same party",shape ="Same party")
1
2
figs/m-district-policy-predicted-senate-[1:2].png
Model Results: Spillover Effects Robustness Check
This is a robustness check for an observable implication of demand-driven behavior. If variation in constituent demand drives variation in legislator behavior (specifically a preference for more senior members), then we should observe spillover effects on the rest of a delegation when an experienced member is replaced with a new member. That is, if people demand more from experienced members, people should redirect demand to the next most experienced member who represents them.
Code
# new IVs: new_senator, new_proportion, new_onedcounts_spillover <- dcounts_per_district %>%# FIRST, identify districts with new members group_by(state, Year) %>%# size of the delegation add_count(name ="n_delegation") %>%mutate(# new IVs:new_senator =ifelse(chamber =="Senate"& new_member ==1, 1, NA), new_proportion =sum(new_member)/n_delegation, new_one =ifelse(new_member ==1, 1, NA) ) %>%fill(new_senator, .direction ="updown") %>%fill(new_one, .direction ="updown") %>%mutate(new_senator =replace_na(new_senator, 0),new_one =replace_na(new_one, 0) ) %>%group_by(state, Year, chamber) %>%arrange(year, state) # THEN WE DROP ALL OF THE NEW MEMBERS dcounts_spillover %<>%filter(new_member ==0) # # inspect data # dcounts_spillover |> select(Year, state, chamber, new_member, new_one, new_senator, new_proportion, perYear) |> ungroup() |># #filter(new_senator ==1) |> # #count(new_senator, new_member) |> # kablebox_long()#
Spillover Effect: Total
Code
m_spillover <-feglm(perYear ~ new_senator | Year + District,cluster ="District",data = dcounts_spillover)# coefplot(m_spillover, horiz = T, drop = "(Intercept)", sub = "") m_spillover_proportion <-feglm(perYear ~ new_proportion | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_proportion, horiz = T, drop = "(Intercept)", sub = "") m_spillover_new_one <-feglm(perYear ~ new_one | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_new_one, horiz = T, drop = "(Intercept)", sub = "")
figs/m-spillover-[1:3].png
Models: models/models_spillover.Rdata
Code
models_spillover <-list("(1)"= m_spillover,"(2)"= m_spillover_proportion,"(3)"= m_spillover_new_one)rows <-tibble(term =c("Dependent variable", "All districts","Senate only"),`(1)`=c("Per year", "✓", ""),`(2)`=c("Per year", "", "✓"),`(3)`=c("Per year", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 9:11)modelsummary(models_spillover,notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year
Per year
Per year
New senator in delegation
3.412
(2.565)
New member in delegation
-14.839*
(6.874)
New proportion in delegation
-16.719
(18.696)
Observations
7,074
1,380
1,380
All districts
✓
Senate only
✓
✓
District fixed effects
X
X
X
Year fixed effects
X
X
X
Code
save(models_spillover, rows, cm, gm, #beta, se,file = here::here("models", "models_spillover.Rdata"))
Spillover Effect: Constituency Service
Code
m_spillover_con <-feglm(perYear_con ~ new_senator | Year + District,cluster ="District",data = dcounts_spillover)# coefplot(m_spillover, horiz = T, drop = "(Intercept)", sub = "") m_spillover_con_proportion <-feglm(perYear_con ~ new_proportion | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_proportion, horiz = T, drop = "(Intercept)", sub = "") m_spillover_con_new_one <-feglm(perYear_con ~ new_one | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_new_one, horiz = T, drop = "(Intercept)", sub = "")
figs/m-spillover-con-[1:3].png
Models: models/models_spillover.Rdata
Code
models_spillover_con <-list("(1)"= m_spillover_con,"(2)"= m_spillover_con_proportion,"(3)"= m_spillover_con_new_one)rows <-tibble(term =c("Dependent variable", "All districts","Senate only"),`(1)`=c("Per year (CS-only)", "✓", ""),`(2)`=c("Per year (CS-only)", "", "✓"),`(3)`=c("Per year (CS-only)", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 9:11)modelsummary(models_spillover_con,notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year (CS-only)
Per year (CS-only)
Per year (CS-only)
New senator in delegation
3.455†
(2.077)
New member in delegation
-12.535*
(6.051)
New proportion in delegation
0.583
(15.486)
Observations
7,074
1,380
1,380
All districts
✓
Senate only
✓
✓
District fixed effects
X
X
X
Year fixed effects
X
X
X
Code
save(models_spillover_con, rows, cm, gm, #beta, se,file = here::here("models", "models_spillover_con.Rdata"))
m_spillover_policy <-feglm(perYear_policy ~ new_senator | Year + District,cluster ="District",data = dcounts_spillover)# coefplot(m_spillover, horiz = T, drop = "(Intercept)", sub = "") m_spillover_policy_proportion <-feglm(perYear_policy ~ new_proportion | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_proportion, horiz = T, drop = "(Intercept)", sub = "") m_spillover_policy_new_one <-feglm(perYear_policy ~ new_one | Year + District,cluster ="District",data = dcounts_spillover |>filter(chamber =="Senate"))# coefplot(m_spillover_new_one, horiz = T, drop = "(Intercept)", sub = "")
figs/m-spillover-policy-[1:3].png
Models: models/models_spillover.Rdata
Code
models_spillover_policy <-list("(1)"= m_spillover_policy,"(2)"= m_spillover_policy_proportion,"(3)"= m_spillover_policy_new_one)rows <-tibble(term =c("Dependent variable", "All districts","Senate only"),`(1)`=c("Per year (Policy-only)", "✓", ""),`(2)`=c("Per year (Policy-only)", "", "✓"),`(3)`=c("Per year (Policy-only)", "", "✓"))# Check marks for controls attr(rows, 'position') <-c(0, 9:11)modelsummary(models_spillover_policy,notes =list("Robust standard errors in parentheses, clustered by district.") )
(1)
(2)
(3)
† p < 0.1, * p < 0.05, ** p < 0.01
Robust standard errors in parentheses, clustered by district.
Dependent variable
Per year (Policy-only)
Per year (Policy-only)
Per year (Policy-only)
New senator in delegation
-0.090
(0.526)
New member in delegation
-1.104
(1.357)
New proportion in delegation
-7.488†
(3.775)
Observations
7,074
1,380
1,380
All districts
✓
Senate only
✓
✓
District fixed effects
X
X
X
Year fixed effects
X
X
X
Code
save(models_spillover_policy, rows, cm, gm, #beta, se,file = here::here("models", "models_spillover_policy.Rdata"))