The Effect of Campaign Contributions on Election Outcome

library(tidyverse)
library(knitr)
library(ggthemes)
house_elections <- read_csv("house_elections.csv")
committees <- read_csv("committees.csv")
candidates <- read_csv("candidates.csv")
load("contributions.rda") 
sum_contr <- 
  contributions %>%
    group_by(cand_id) %>%
    summarise(contr_sum = sum(transaction_amt))
house_elections <-
  rename(house_elections, cand_id = fec_id)
elect_cand_contr <-
house_elections %>%
  inner_join(candidates, by = "cand_id") %>%
  inner_join(sum_contr, by = "cand_id") %>%
  select(cand_id, candidate_name, state, district, party, cand_ici, primary_votes, general_votes, ge_winner, contr_sum)%>%
  rename(incum = cand_ici)

In political science, the question of money’s affect on the outcome of elections is a popular research topic. Although the general consensus is that money plays some role in the success or failure of a candidate, the true magnitude of its effect is largely unknown. The amount of money in politics has increasd significantly over past years and continues to rise. With the creation of political action committees (PACs) and presidential candidates raising hundreds of millions of dollars, attention is often focused at the national level, but the role that money plays in state and local elections is equally interesting and important. Calls for campaign finance reform beg the question; how much does money actually matter in the outcome of elections? It certainly seems better to have some money than no money, and it’s unlikely that more money could hurt a candidate. It’s also reasonable to expect that there are diminishing returns to campaign contributions. The first million dollars that you spend probably has a greater effect than the second or third.

Despite the availability of good data from the FEC on campaign contributions, this remains a difficult question to answer. One problem when trying to answer this question is establishing causality. Is it that candidates who are able to raise more money are more likely to win as a result of that money, or is it that popular candidates tend to raise more money than the opposition and are more likely to win in the first place. There are also a number of other factors that influence the chances that a candidate will win such as whether they are an incumbent or a challenger.

Table 1: Contributions of winners and losers

table1_names <- c("Won general election?", "Average total campaign contributions")
elect_cand_contr %>%
  group_by(ge_winner) %>%
  summarise(contr = mean(contr_sum)) %>%
  kable(align = "c", col.names = table1_names, caption = "Average total contributions received by election winners and losers")
Average total contributions received by election winners and losers
Won general election? Average total campaign contributions
N 347372.3
W 1040502.8

This table shows the average sum of campaign contributions that candidates received separated by whether they won or lost the general election. On average, election winners received nearly three times as much money as election losers. At first glance, it seems that money plays a huge role in election outcome, but this table fails to capture the whole picture and doesn’t include things like how many people actually voted for the candidate, their district, or how much money the winner raised compared to their opponents. Congressional districts are formed to have the same population within states, but can vary in size from state to state.

Table 2: Above or below the average number of votes?

table2_names <- c("Above average votes received", "Average total campaign contributions")
elect_cand_contr %>%
  mutate(avg_turnout = mean(general_votes)) %>%
  group_by(general_votes >= avg_turnout) %>%
  summarise(avg = mean(contr_sum)) %>%
  kable(col.names = table2_names, align = "c", caption = "Average total contributions for candidates with greater or less than the average number of votes won")
Average total contributions for candidates with greater or less than the average number of votes won
Above average votes received Average total campaign contributions
FALSE 154064.2
TRUE 1037306.6

Table 2 separates candidates into whether they received more or fewer votes than the average candidate. Candidates who received more votes than average are more likely to be successful so it seems useful to see if they also received more contributions. The numbers above suggest that this is the case. However, the numbers in Table 2, and also Table 1, likely overstate the effect of money in elections. For Table 2, the numbers fail to control for the size of districts and the turnout rate within those districts. On average, candidates who run for office in districts with larger populations will receive more votes and probably more campaign contributions. Varying turnout rates in districts is also interesting and important to consider. It could be that a higher portion of the population vote in a close election. It also important to consider that most house elections are not actually that close. It’s likely that the amount of money spent would increase as the margin of victory decreases since there is little incentive to spend large amounts of money in elections that expected to be landslide wins or losses.

total_vote_contr <-
elect_cand_contr %>%
  group_by(state, district) %>%
  summarise(total_district_vote = sum(general_votes),
            total_district_contr = sum(contr_sum))
final_data <-
elect_cand_contr %>%
  full_join(total_vote_contr, by = c("state","district")) %>%
  arrange(desc(state, district))

Table 3: Contributions compared to the opposition

table3_names <- c("Contributions less than half?", "Election victory", "Frequency")
final_data %>%
  group_by(contr_sum<0.5*total_district_contr, ge_winner) %>%
  summarise(num = n()) %>%
  kable(align = "c", col.names = table3_names, caption = "Average total contibutions when controlling for state and district")
Average total contibutions when controlling for state and district
Contributions less than half? Election victory Frequency
FALSE N 42
FALSE W 397
TRUE N 595
TRUE W 41

This table attempts to approach the question in a slightly different way. How many times did someone raise more than half the total amount contributed within their district but still lose and vice versa? The vast majority of candidates who won outspent their opponent. Similarly, candidates who lost were very likely to have been outspent by the oppostion. By finding the total amount of contributions and votes in each state district, we can begin to control for differences between different states and districts. Instead of looking only at average votes or average contributions across all districts, we looked at contributions compared to the total amount for each district. It is more informative to compare the outcomes of candidates in the same district than the average candidate in the United States.

Figure 1

ggplot(final_data, aes(y = general_votes/total_district_vote*100, x = contr_sum/total_district_contr*100, color = ge_winner))+
  geom_point(alpha = 0.5)+
  labs(y = "Pct votes won", x = "Contributions relative to district", title = "Contributions and vote percentage", subtitle = "Election winners and losers")+
  geom_smooth(se=FALSE, method = "lm")+
  theme(legend.title = element_blank(), panel.background = element_rect(color = "azure1"), panel.grid.major = element_line(color = "grey"), panel.grid.minor = element_line(color = "grey"))+
  annotate("text", x = 70, y = 72, label = "W slope = 0.45")+
  annotate("text", x = 55, y = 35, label = "N slope = 0.52")

Slope of winner regression line
final_data %>% 
  mutate(vote_pct = general_votes/total_district_vote,
         contr_pct = contr_sum/total_district_contr) %>%
  filter(ge_winner == "W") %>%
  lm(formula = vote_pct ~ contr_pct)
## 
## Call:
## lm(formula = vote_pct ~ contr_pct, data = .)
## 
## Coefficients:
## (Intercept)    contr_pct  
##      0.3363       0.4538
Slope of loser regression line
final_data %>% 
  mutate(vote_pct = general_votes/total_district_vote,
         contr_pct = contr_sum/total_district_contr) %>%
  filter(ge_winner == "N") %>%
  lm(formula = vote_pct ~ contr_pct)
## 
## Call:
## lm(formula = vote_pct ~ contr_pct, data = .)
## 
## Coefficients:
## (Intercept)    contr_pct  
##      0.1410       0.5196

Figure 2

final_data %>%
  filter(general_votes/total_district_vote != 0 & general_votes/total_district_vote != 1)%>% 
ggplot(aes(y = general_votes/total_district_vote*100, x = contr_sum/total_district_contr*100, color = ge_winner))+
  geom_point(alpha = 0.5)+
  labs(y = "Pct votes won", x = "Contributions relative to district", title = "Contributions and vote percentage", subtitle = "Unopposed candidates and candidates with 0 votes removed")+
  geom_smooth(se=FALSE, method = "lm")+
  theme(legend.title = element_blank())+
  annotate("text", x = 10, y = 55, label = "W slope = 0.21")+
  annotate("text", x = 20, y = 30, label = "N slope = 0.33")+
  theme(legend.title = element_blank(), panel.background = element_rect(color = "azure1"), panel.grid.major = element_line(color = "grey"), panel.grid.minor = element_line(color = "grey"))

Winner slope
final_data %>% 
  mutate(vote_pct = general_votes/total_district_vote,
         contr_pct = contr_sum/total_district_contr) %>%
  filter(ge_winner == "W") %>%
  filter(general_votes/total_district_vote != 0 & general_votes/total_district_vote != 1) %>%
  lm(formula = vote_pct ~ contr_pct)
## 
## Call:
## lm(formula = vote_pct ~ contr_pct, data = .)
## 
## Coefficients:
## (Intercept)    contr_pct  
##      0.4587       0.2072
Loser slope
final_data %>% 
  mutate(vote_pct = general_votes/total_district_vote,
         contr_pct = contr_sum/total_district_contr) %>%
  filter(ge_winner == "N") %>%
  filter(general_votes/total_district_vote != 0 & general_votes/total_district_vote != 1) %>%
  lm(formula = vote_pct ~ contr_pct)
## 
## Call:
## lm(formula = vote_pct ~ contr_pct, data = .)
## 
## Coefficients:
## (Intercept)    contr_pct  
##      0.3100       0.3278

Figure 3

final_data %>%
  filter(general_votes/total_district_vote != 0 & general_votes/total_district_vote != 1)%>% 
  filter(contr_sum/total_district_contr !=0 & contr_sum/total_district_contr !=1) %>%
ggplot(aes(y = general_votes/total_district_vote*100, x = contr_sum/total_district_contr*100, color = incum))+
  geom_point(alpha = 0.5)+
   labs(y = "Pct votes won", x = "Contributions relative to district", title = "Contributions and vote percentage", subtitle = "Unopposed candidates and candidates with 0 votes, 0 contributions, or 100% of contributions removed")+
  geom_smooth(se=FALSE, method = "lm")+
  theme(legend.title = element_blank())+
  theme(legend.title = element_blank(), panel.background = element_rect(color = "azure1"), panel.grid.major = element_line(color = "grey"), panel.grid.minor = element_line(color = "grey"))

Figures 1-3 plot the percentage of the vote that a candidate won and the contributions that they received relative to the total votes and contributions in their district. Figures 1 and 2 separate candidates by whether they won or lost. There is a positive relationship between contributions and vote percentage for both candidates who won and lost. Interestingly, the impact was slightly larger for losing candidates. In Figure 2, we removed candidates who either won 100% or 0% of the vote. Candidates who won 100% of the votes were most likely running unopposed. Contributions in uncontested races do not impact the outcome. We also excluded candidates who received 0 votes. These were likely candidates who did not receive enough primary votes to make it on to the ballot for the general election. Both of these cases skew the results so we excluded them. Figure 3 separates candidates by whether they are an incumbent, challenger, or running for an open seat. We also removed candidates who received either 100% or 0% of the vote in this plot, as well as candidates who received either all contributions within their district or no contributions. Filtering out candidates who had 0 or 100% of contributions had little impact on the results. Figure 3 shows that campaign contributions have the largest effect for challengers. It has less of an effect for candidates running for an open seat, and even less of an effect for incumbents.