Exploring the Intersection of Economic Status and Voting Behavior: Insight from Palm Beach County’s 2016 Penny Tax Initiative

The 2016 Penny Tax initiative in Palm Beach County sought to provide essential funding for school repairs, renovations, and improvements through a 1% increase on local sales tax. Approved by 56.3% of voters during the November 2016 General Election, the tax was labeled on the ballot as County Question 1. This project examines the potential relationship between economic status and voting behavior. By integrating precinct-level election results with economic markers, like median household income from the Census Bureau at the block group level, this analysis seeks to explore the economic influence on voter approval of the 2016 Penny Tax. The graphs below seek to reveal patterns in voter support for school funding initiatives linked to sales tax increases, as well as provide insights into community characteristics of Palm Beach County precincts.

Working with Precinct Data and the Palm Beach Shapefile

library(tidyverse)
library(readxl)
library(sf)
library(tidycensus)
library(ggplot2)
library(dplyr)
library(patchwork)

County Question 1 Election Results

The 2016 November General Election results can be found through the Florida Division of Elections site. These files were downloaded as an Excel spreadsheet to clean and sort through the data, and moved into a CSV file with the condensed information.

  • Downloading CSV file:
election_data2016 <- read_csv("/Users/dalia/Downloads/election_data2016(Sheet1).csv")
  • Handling NAs in Data and Turning Into 0s:
election_data2016 <- election_data2016 |>
  mutate( 
    `For Tax` = if_else(is.na(`For Tax`), 0, `For Tax`),
    `Against Tax` = if_else(is.na(`Against Tax`), 0, `Against Tax`)
  )

Palm Beach County Precinct Map

I was able to obtain the shapefiles necessary to visualize the Palm Beach Precincts through the UF Election Data Lab website.

  • Importing the Precinct Map:
precinct_map <- st_read("/Users/dalia/Downloads/fl_2016")
## Reading layer `fl_2016' from data source `/Users/dalia/Downloads/fl_2016' using driver `ESRI Shapefile'
## Simple feature collection with 6116 features and 18 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY, XYZ
## Bounding box:  xmin: -87.6349 ymin: 24.39631 xmax: -79.97431 ymax: 31.00097
## z_range:       zmin: 0 zmax: 0
## Geodetic CRS:  NAD83
  • Narrowing Down Palm Beach Only:
palm_beach_shapefile <- precinct_map |>
  filter(COUNTY == "PAL")
  • Plotting Palm Beach Only:
plot(st_geometry(palm_beach_shapefile))

Merging Precinct Results with Palm Beach Map

  • Preparing for Merge:

This code helped ensure that the precinct numbers were treated as characters and not numerical values.

palm_beach_shapefile$PRECINCT <- as.character(palm_beach_shapefile$PRECINCT)
election_data2016$Precinct <- as.character(election_data2016$Precinct)
  • Merging Data sets:

This merged the election results CSV file with the Palm Beach shapefile.

palm_beach_shapefile_merged <- palm_beach_shapefile |>
  left_join(election_data2016, by = c("PRECINCT" = "Precinct")) |>
  mutate(
    `For Tax` = if_else(is.na(`For Tax`), 0, `For Tax`),
    `Against Tax` = if_else(is.na(`Against Tax`), 0, `Against Tax`)
  )
  • Checking success of the Merge:

In order to make sure that the merge had been successful, and that each Precinct had been present, I checked the number of rows in the the original shapefile and the newly merged shapefile. This was successful as both numbers matched.

nrow(palm_beach_shapefile)
## [1] 938
nrow(palm_beach_shapefile_merged)
## [1] 938

Graphing Relationships

  • Mapping Precincts with Voting Results- Count For the Tax:

In order to work with the merged file, the data had to be made valid to work with. Once this was done, I could now make a visual that identified the number of votes present in each precinct in favor of the tax.

palm_beach_shapefile_merged <- st_make_valid(palm_beach_shapefile_merged) 

ggplot(data = palm_beach_shapefile_merged) +
  geom_sf(aes(fill = `For Tax`)) +
  scale_fill_viridis_c() +
  labs(title = "Palm Beach County Precincts: Votes For Tax", fill = "Votes For Tax") +
  theme_minimal()

Mapping Precincts with Voting Results- Proportion For the Tax:

This map visualizes the proportion, rather than the count, of votes in favor of the tax, per precinct.

palm_beach_shapefile_merged <- palm_beach_shapefile_merged |>
  mutate(for_tax_pct = `For Tax` / (`For Tax` + `Against Tax`))

ggplot(data = palm_beach_shapefile_merged) +
  geom_sf(aes(fill = for_tax_pct)) +
  scale_fill_viridis_c() +
  labs(
    title = "Support for 2016 Penny Tax by Precinct",
    fill = "Proportion For Tax"
  ) +
  theme_minimal()

Bringing Census Data and Precinct Data Together

Census Data

  • Gathering Census Variables for Block Groups in Palm Beach:

The median income data was obtained through the TidyCensus package. This information was turned into a data set to work with.

census_data <- get_acs(
  geography = "block group",
  variables = c(median_income = "B19013_001"),
  state = "FL",
  county = "Palm Beach",
  geometry = TRUE
) |>
  select(GEOID, NAME, estimate, geometry) |>
  rename(median_income = estimate)
##   |                                                                              |                                                                      |   0%  |                                                                              |=                                                                     |   1%  |                                                                              |=                                                                     |   2%  |                                                                              |==                                                                    |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |===                                                                   |   4%  |                                                                              |===                                                                   |   5%  |                                                                              |====                                                                  |   5%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |=====                                                                 |   8%  |                                                                              |======                                                                |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |=======                                                               |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |==========                                                            |  14%  |                                                                              |==========                                                            |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  18%  |                                                                              |==============                                                        |  20%  |                                                                              |===============                                                       |  21%  |                                                                              |===============                                                       |  22%  |                                                                              |================                                                      |  23%  |                                                                              |================                                                      |  24%  |                                                                              |=================                                                     |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |===================                                                   |  28%  |                                                                              |====================                                                  |  28%  |                                                                              |====================                                                  |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |======================                                                |  32%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |========================                                              |  34%  |                                                                              |=========================                                             |  36%  |                                                                              |==========================                                            |  37%  |                                                                              |===========================                                           |  39%  |                                                                              |============================                                          |  40%  |                                                                              |============================                                          |  41%  |                                                                              |=============================                                         |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |===============================                                       |  44%  |                                                                              |================================                                      |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |=================================                                     |  48%  |                                                                              |==================================                                    |  48%  |                                                                              |===================================                                   |  50%  |                                                                              |=====================================                                 |  54%  |                                                                              |======================================                                |  54%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  57%  |                                                                              |========================================                              |  58%  |                                                                              |=========================================                             |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |===========================================                           |  61%  |                                                                              |============================================                          |  62%  |                                                                              |============================================                          |  63%  |                                                                              |==============================================                        |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  66%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  71%  |                                                                              |==================================================                    |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |====================================================                  |  74%  |                                                                              |=====================================================                 |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  78%  |                                                                              |=======================================================               |  78%  |                                                                              |========================================================              |  79%  |                                                                              |========================================================              |  80%  |                                                                              |=========================================================             |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  82%  |                                                                              |==========================================================            |  84%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |=============================================================         |  87%  |                                                                              |===============================================================       |  90%  |                                                                              |================================================================      |  92%  |                                                                              |==================================================================    |  94%  |                                                                              |===================================================================   |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |===================================================================== |  98%  |                                                                              |======================================================================| 100%
  • Checking Coordinate Compatibility:

Necessary to properly merge with the Palm Beach precinct shapefile.

census_data <- st_transform(census_data, st_crs(palm_beach_shapefile_merged))
  • Matching Block Groups to Precincts on a Spatial Overlap:
palm_beach_with_census <- st_join(palm_beach_shapefile_merged, census_data, join = st_intersects)
  • Aggregating Precincts with Multiple Blocks:

To make the data clearer, I aggregated the data for precincts that held multiple blocks within them. This would allow the Census data to be reflect all of the blocks within a singular precinct.

PB_with_census_summary <- palm_beach_with_census |>
  group_by(PRECINCT) |>
  summarize(
    avg_median_income = mean(median_income, na.rm = TRUE)
  )
  • Graphing Average Median Income:

With the information now in a singular data set, this visual shows the average median income for the Palm Beach Precincts, rather than for the Census Blocks.

ggplot(data = PB_with_census_summary) +
  geom_sf(aes(fill = avg_median_income)) +
  scale_fill_viridis_c(na.value = "grey80") + 
  labs(
    title = "Palm Beach Precincts: Average Median Income",
    fill = "Median Income"
  ) +
  theme_minimal()

Comparing Precincts Average Median Income Map with Block Group Average Median Income Map

  • Loading Census Data for Palm Beach Block Groups:
census_block_groups <- get_acs(
  geography = "block group",
  variables = c(median_income = "B19013_001"),
  state = "FL",
  county = "Palm Beach",
  geometry = TRUE
)
  • Changing median_income variable:
census_block_groups_summary <- census_block_groups |>
  mutate(
    median_income = estimate
  )
  • Graphing Block Group Average Median Income:

This map, unlike the one above, showcases the median average income only for the divisions provided by the Census Block groups. This map, therefore, does not reflect any information about the geographical divisions for electoral precincts.

ggplot(data = census_block_groups_summary) +
  geom_sf(aes(fill = median_income)) +
  scale_fill_viridis_c(na.value = "grey80") +
  labs(
    title = "Palm Beach Block Groups: Average Median Income",
    fill = "Median Income"
  ) +
  theme_minimal()

A Deeper Look at the Precinct Election Results

A Scatter Plot to Visualize Relationship between Average Median Income and Percentage of Voters for the Tax

  • Creating new data frame to hold both average median income and the For & Against Votes:
PB_with_census_summary_df <- as.data.frame(PB_with_census_summary)

merged_data <- palm_beach_with_census |>
  left_join(PB_with_census_summary_df, by = "PRECINCT")
  • Scatter plot of average median income vs. proportion of votes for tax:

Through this map, we can visualize how as median income increases, there is a slight decrease in the support towards the tax increase. The data points at 1.00 proportion of votes indicate precincts where there were no votes against the tax, whereas points at 0.00 proportion indicate precincts where there were no votes cast in favor of the tax.

ggplot(data = merged_data) +
  geom_point(aes(x = avg_median_income, y = `For Tax` / (`For Tax` + `Against Tax`)),
             color = "blue", alpha = 0.6) +
  geom_smooth(aes(x = avg_median_income, y = `For Tax` / (`For Tax` + `Against Tax`)), 
              method = "lm", color = "red", se = FALSE) +
  labs(
    title = "Relationship Between Median Income and Support for Tax",
    x = "Average Median Income",
    y = "Proportion of Votes For Tax"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Dual Heatmap to Visualize Votes For Tax and Median Income

  • Creating two maps side-by-side:

To further visualize similarities and differences between how precincts with higher vs lower median incomes voted for the tax, this visual shows 2 maps next to each other. The first holds information on the median income by precinct, which can be visually compared with the second, which shows which areas voted For the Tax.

p1 <- ggplot(data = merged_data) +
  geom_sf(aes(fill = avg_median_income)) +
  scale_fill_viridis_c(option = "plasma") +
  labs(title = "Median Income by Precinct", fill = "Median Income") +
  theme_minimal()

p2 <- ggplot(data = merged_data) +
  geom_sf(aes(fill = `For Tax`)) +
  scale_fill_viridis_c(option = "plasma") +
  labs(title = "Votes For Tax by Precinct", fill = "Votes For Tax") +
  theme_minimal()

library(patchwork)
p1 + p2

Final Reflections

Through this project, I was able to explore at greater depth the economic status, through median income, of supporters of the 2016 Penny Tax initiative. The regression line analysis was one of the most significant visuals I created to display the possible relationship between these variables, and although slight, there does appear to be a decrease in support for the Penny Tax as the annual median income increases.

The maps within the Graphing Relationships section help visualize the overall support for the Penny tax in Palm Beach, and the Bringing Census Data and Precinct Data Together visuals highlight the work I did to be able to merge Census Block group data with the precinct results. My final map, within the Dual Heatmap to Visualize Votes… section serves as a final visual reference to compare the precincts with the greatest support for the Penny tax and to those with the greatest media incomes in the county.

Overall, some of the biggest challenges I faced throughout this project involved working with the original spreadsheet containing the election results at the precinct level and managing the data sets through the different merges. The documentation from the Florida Division of Elections contained much more information than the necessary for this project. In order to make the data possible to work with, I had to manually sort through precincts to obtain only the Total Count for each. I was able to use R to then adjust the sets when making certain variables characters, managing NAs, etc. In addition, the data sets changed multiple times when working through merges. I was surprised that to make different visuals, I would have to alter my sets in different manners (not a one-size-fits-all scenario like I was hoping for). Finally, I was worried through the merging of the geographies, and had trouble deciding what how to best visually represent the information.

In the end, this project was a great opportunity to work with election data relevant to both my hometown and my passion for school finance research. I believe this project would be helpful in the future when determining the success of similar tax initiatives and tax increases, and could hopefully highlight what populations are more likely to support them. Further research could be conducted to look at other income signifiers, like reliance on SNAP programs, or considerations like voting roll-off.