# CAMPAIGN RECEIPTS BY PARTY AND INCUMBENCY STATUS
# Standalone script for creating visualizations of campaign finance data by categories
# Load necessary packages
if (!require("ggplot2")) install.packages("ggplot2")
## Loading required package: ggplot2
if (!require("gridExtra")) install.packages("gridExtra")
## Loading required package: gridExtra
if (!require("dplyr")) install.packages("dplyr")
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:gridExtra':
##
## combine
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
if (!require("viridis")) install.packages("viridis")
## Loading required package: viridis
## Loading required package: viridisLite
if (!require("scales")) install.packages("scales")
## Loading required package: scales
##
## Attaching package: 'scales'
## The following object is masked from 'package:viridis':
##
## viridis_pal
library(ggplot2) # For creating plots
library(gridExtra) # For arranging multiple plots
library(dplyr) # For data manipulation
library(viridis) # For better color palettes
library(scales) # For scale formatting
# Set global theme for all plots
theme_set(theme_minimal(base_size = 12) +
theme(plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 12, color = "gray30"),
axis.title = element_text(face = "bold"),
legend.title = element_text(face = "bold"),
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_line(color = "gray95"),
plot.background = element_rect(fill = "white", color = NA),
legend.background = element_rect(fill = "white", color = NA)))
# Create or load your data
# OPTION 1: Comment out this block if loading your own data
set.seed(123)
n <- 500
campaign_data <- data.frame(
receipts = rlnorm(n, meanlog = 10, sdlog = 1),
individual_contributions = rlnorm(n, meanlog = 9.5, sdlog = 1.2),
disbursements = rlnorm(n, meanlog = 9.8, sdlog = 0.9),
party = factor(sample(c("Democrat", "Republican"), n, replace = TRUE)),
incumbency = factor(sample(c("Incumbent", "Challenger", "Open Seat"), n, replace = TRUE))
)
# OPTION 2: Uncomment to load your own data
# campaign_data <- read.csv("your_data_file.csv")
# Create log transformed variables for better visualization
campaign_data$log_receipts <- log(campaign_data$receipts + 1) # Add 1 to handle zeros
campaign_data$log_individual_contributions <- log(campaign_data$individual_contributions + 1)
campaign_data$log_disbursements <- log(campaign_data$disbursements + 1)
# Calculate summary statistics
finance_summary <- campaign_data %>%
group_by(party, incumbency) %>%
summarize(
mean_receipts = mean(receipts, na.rm = TRUE),
median_receipts = median(receipts, na.rm = TRUE),
mean_individual_contributions = mean(individual_contributions, na.rm = TRUE),
median_individual_contributions = median(individual_contributions, na.rm = TRUE),
mean_disbursements = mean(disbursements, na.rm = TRUE),
median_disbursements = median(disbursements, na.rm = TRUE),
count = n()
)
## `summarise()` has grouped output by 'party'. You can override using the
## `.groups` argument.
# Print summary table
print(finance_summary)
## # A tibble: 6 × 9
## # Groups: party [2]
## party incumbency mean_receipts median_receipts mean_individual_contribu…¹
## <fct> <fct> <dbl> <dbl> <dbl>
## 1 Democrat Challenger 35007. 24543. 22246.
## 2 Democrat Incumbent 32902. 22516. 24288.
## 3 Democrat Open Seat 35911. 20464. 30232.
## 4 Republican Challenger 47031. 23464. 37412.
## 5 Republican Incumbent 36448. 24212. 23648.
## 6 Republican Open Seat 33611. 19962. 28829.
## # ℹ abbreviated name: ¹mean_individual_contributions
## # ℹ 4 more variables: median_individual_contributions <dbl>,
## # mean_disbursements <dbl>, median_disbursements <dbl>, count <int>
# Function to create boxplots
create_boxplots <- function(data) {
# 1. Boxplot of receipts by party and incumbency
p1 <- ggplot(data, aes(x = incumbency, y = receipts, fill = party)) +
geom_boxplot(alpha = 0.8) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Campaign Receipts by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Total Receipts ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# 2. Boxplot of log receipts by party and incumbency
p2 <- ggplot(data, aes(x = incumbency, y = log_receipts, fill = party)) +
geom_boxplot(alpha = 0.8) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
labs(title = "Log-Transformed Campaign Receipts",
subtitle = "Natural logarithm of receipts",
x = "Incumbency Status",
y = "Log(Total Receipts)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# 3. Boxplot of individual contributions by party and incumbency
p3 <- ggplot(data, aes(x = incumbency, y = individual_contributions, fill = party)) +
geom_boxplot(alpha = 0.8) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Individual Contributions by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Individual Contributions ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# 4. Boxplot of disbursements by party and incumbency
p4 <- ggplot(data, aes(x = incumbency, y = disbursements, fill = party)) +
geom_boxplot(alpha = 0.8) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Campaign Disbursements by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Total Disbursements ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# Return list of plots
return(list(
receipts = p1,
log_receipts = p2,
individual_contributions = p3,
disbursements = p4
))
}
# Function to create bar charts of mean values
create_bar_charts <- function(summary_data) {
# 1. Bar chart of mean receipts
p1 <- ggplot(summary_data, aes(x = incumbency, y = mean_receipts, fill = party)) +
geom_col(position = "dodge", alpha = 0.8) +
geom_text(aes(label = paste0("$", round(mean_receipts/1000, 1), "K")),
position = position_dodge(width = 0.9),
vjust = -0.5, size = 3.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Mean Campaign Receipts by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Mean Total Receipts ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# 2. Bar chart of mean individual contributions
p2 <- ggplot(summary_data, aes(x = incumbency, y = mean_individual_contributions, fill = party)) +
geom_col(position = "dodge", alpha = 0.8) +
geom_text(aes(label = paste0("$", round(mean_individual_contributions/1000, 1), "K")),
position = position_dodge(width = 0.9),
vjust = -0.5, size = 3.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Mean Individual Contributions by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Mean Individual Contributions ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# 3. Bar chart of mean disbursements
p3 <- ggplot(summary_data, aes(x = incumbency, y = mean_disbursements, fill = party)) +
geom_col(position = "dodge", alpha = 0.8) +
geom_text(aes(label = paste0("$", round(mean_disbursements/1000, 1), "K")),
position = position_dodge(width = 0.9),
vjust = -0.5, size = 3.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
scale_y_continuous(labels = dollar_format(scale = 1e-3, suffix = "K")) +
labs(title = "Mean Campaign Disbursements by Party and Incumbency Status",
subtitle = "Dollar amounts in thousands",
x = "Incumbency Status",
y = "Mean Total Disbursements ($)",
fill = "Party") +
theme(axis.text.x = element_text(angle = 0, hjust = 0.5))
# Return list of plots
return(list(
mean_receipts = p1,
mean_individual_contributions = p2,
mean_disbursements = p3
))
}
# Function to create density plots
create_density_plots <- function(data) {
# 1. Density plot of log receipts by party
p1 <- ggplot(data, aes(x = log_receipts, fill = party)) +
geom_density(alpha = 0.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
labs(title = "Distribution of Log Receipts by Party",
x = "Log(Total Receipts)",
y = "Density",
fill = "Party") +
theme(legend.position = "top")
# 2. Density plot of log individual contributions by party
p2 <- ggplot(data, aes(x = log_individual_contributions, fill = party)) +
geom_density(alpha = 0.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
labs(title = "Distribution of Log Individual Contributions by Party",
x = "Log(Individual Contributions)",
y = "Density",
fill = "Party") +
theme(legend.position = "top")
# 3. Density plot of log disbursements by party
p3 <- ggplot(data, aes(x = log_disbursements, fill = party)) +
geom_density(alpha = 0.5) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
labs(title = "Distribution of Log Disbursements by Party",
x = "Log(Total Disbursements)",
y = "Density",
fill = "Party") +
theme(legend.position = "top")
# 4. Faceted density plots by incumbency status
p4 <- ggplot(data, aes(x = log_receipts, fill = party)) +
geom_density(alpha = 0.5) +
facet_wrap(~ incumbency, ncol = 1) +
scale_fill_manual(values = c("Democrat" = "#3366FF", "Republican" = "#FF3333")) +
labs(title = "Distribution of Log Receipts by Party and Incumbency Status",
x = "Log(Total Receipts)",
y = "Density",
fill = "Party") +
theme(legend.position = "top")
# Return list of plots
return(list(
log_receipts_density = p1,
log_contributions_density = p2,
log_disbursements_density = p3,
faceted_density = p4
))
}
# Generate all plots
boxplots <- create_boxplots(campaign_data)
bar_charts <- create_bar_charts(finance_summary)
density_plots <- create_density_plots(campaign_data)
# Display specific plots
# Uncomment whichever plots you want to see
print(boxplots$receipts)

# print(boxplots$log_receipts)
# print(boxplots$individual_contributions)
# print(boxplots$disbursements)
# print(bar_charts$mean_receipts)
# print(bar_charts$mean_individual_contributions)
# print(bar_charts$mean_disbursements)
# print(density_plots$log_receipts_density)
# print(density_plots$faceted_density)
# Create a function to arrange and display all plots in a grid
display_all_plots <- function() {
# Arrange boxplots
boxplot_grid <- grid.arrange(
boxplots$receipts,
boxplots$log_receipts,
boxplots$individual_contributions,
boxplots$disbursements,
ncol = 2
)
# Arrange bar charts
bar_grid <- grid.arrange(
bar_charts$mean_receipts,
bar_charts$mean_individual_contributions,
bar_charts$mean_disbursements,
ncol = 2
)
# Arrange density plots
density_grid <- grid.arrange(
density_plots$log_receipts_density,
density_plots$log_contributions_density,
density_plots$log_disbursements_density,
density_plots$faceted_density,
ncol = 2
)
# Return the grid objects
return(list(
boxplot_grid = boxplot_grid,
bar_grid = bar_grid,
density_grid = density_grid
))
}
# Save plots to PDF
save_plots_to_pdf <- function(filename = "campaign_finance_by_category.pdf") {
pdf(filename, width = 11, height = 8.5)
# Title page
plot.new()
title <- "Campaign Finance by Party and Incumbency Status"
subtitle <- paste("Generated:", format(Sys.time(), "%B %d, %Y"))
text(0.5, 0.6, title, cex = 2, font = 2)
text(0.5, 0.5, subtitle, cex = 1.2)
# Print boxplots
grid.arrange(
boxplots$receipts,
boxplots$log_receipts,
boxplots$individual_contributions,
boxplots$disbursements,
ncol = 2,
top = "Boxplots of Campaign Finance Data"
)
# Print bar charts
grid.arrange(
bar_charts$mean_receipts,
bar_charts$mean_individual_contributions,
bar_charts$mean_disbursements,
ncol = 2,
top = "Mean Campaign Finance Values by Category"
)
# Print density plots
grid.arrange(
density_plots$log_receipts_density,
density_plots$log_contributions_density,
density_plots$log_disbursements_density,
ncol = 2,
top = "Distributions of Campaign Finance Variables"
)
print(density_plots$faceted_density)
dev.off()
cat("All plots saved to", filename, "\n")
}
# Uncomment to display all plots in a grid arrangement
# all_plots <- display_all_plots()
# Uncomment to save all plots to PDF
# save_plots_to_pdf()