Analyzing Transparency of Taxpayer Fund Distribution and Economic Outcomes in Maryland
1.Introduction
Maryland distributes billions of dollars through grants and loans to counties, institutions, and organizations. Public funding is intended to support development, strengthen communities, and improve economic opportunity.
This project evaluates whether those public investments are associated with stronger worker wages.
Specifically, I compare two major Maryland counties:
Montgomery County Prince George’s County
These neighboring counties are ideal comparisons because they receive major state support but differ economically.
Research Question
To what extent do Maryland State Grants and Loans correlate with the growth of Average Wage Per Job between 2014 and 2024?
Load Libraries
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.4 ✔ tidyr 1.3.1
✔ purrr 1.0.4
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dplyr)library(janitor)
Attaching package: 'janitor'
The following objects are masked from 'package:stats':
chisq.test, fisher.test
library(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
library(leaflet)library(sf)
Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
library(tigris)
To enable caching of data, set `options(tigris_use_cache = TRUE)`
in your R script or .Rprofile.
library(scales)
Attaching package: 'scales'
The following object is masked from 'package:purrr':
discard
The following object is masked from 'package:readr':
col_factor
library(readr)
Load Datasets
# Dataset 1 = Maryland grants and loanssetwd("~/Desktop/Data 110")grants <-read.csv("State_of_Maryland_Grant_and_Loan_Data__FY2009_to_FY2024.csv")# Dataset 2 = Average wage per jobsetwd("~/Desktop/Data 205")wages <-read.csv("Maryland_Average_Wage_Per_Job_(Current_Dollars)__2014-2024_20260414.csv")# Dataset 3 = ZIP code lookup tablezip_lookup <-read_csv("Zip_Code_Lookup_Table_20260414.csv")
Rows: 619 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): City, County
dbl (1): Zip Code
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Clean & Prepare Data
# Clean column namesgrants <-clean_names(grants)wages <-clean_names(wages)zip_lookup <-clean_names(zip_lookup)# Convert ZIP to textzip_lookup <- zip_lookup %>%mutate(zip_code =as.character(zip_code))
Reshaping the Wage Data
# Convert wage data into long format for easier mergingwages_long <- wages %>%rename(year =2) %>%select(year, montgomery_county, prince_george_s_county) %>%pivot_longer(cols =-year,names_to ="county",values_to ="avg_wage") %>%mutate(county =case_when( county =="montgomery_county"~"Montgomery County", county =="prince_george_s_county"~"Prince George's County" ),year =as.numeric(year) )
Clean Grants Data
# Match grants to counties using ZIP codes# Then total yearly funding for each countygrants_clean <- grants %>%mutate(zip_code =as.character(zip_code),fiscal_year =as.numeric(fiscal_year) ) %>%left_join(zip_lookup, by ="zip_code") %>%filter(county %in%c("Montgomery County", "Prince George's County")) %>%group_by(fiscal_year, county) %>%summarize(total_grant_amount =sum(amount, na.rm =TRUE),.groups ="drop" )
Merge Datasets
# Final dataset combines funding and wagesdf <- grants_clean %>%inner_join(wages_long,by =c("fiscal_year"="year","county"="county"))df <- df %>%mutate(avg_wage =parse_number(avg_wage))
# A tibble: 2 × 2
county correlation
<chr> <dbl>
1 Montgomery County 0.882
2 Prince George's County 0.794
Interpretation
“While funding and wage growth are strongly correlated, this relationship is associative rather than causal. Montgomery County’s higher correlation suggests more efficient conversion of public investment into high-wage sectors. In Prince George’s County, a more moderate correlation indicates that external factors—such as labor market conditions or industry mix—may dampen the economic impact of state funding.”
STATISTICAL TESTING:Pearson Correlation Test
Q: Is there statistically significant evidence of a positive linear relationship between state grant funding and average wages in each county?
\(H_0\): p = 0 \(H_a\): p > 0
Montgomery County
df %>%filter(county =="Montgomery County") %>%with(cor.test(total_grant_amount, avg_wage))
Pearson's product-moment correlation
data: total_grant_amount and avg_wage
t = 5.6112, df = 9, p-value = 0.0003295
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.5987391 0.9690875
sample estimates:
cor
0.881873
Montgomery County shows a strong, statistically significant positive correlation between funding and wages (\(r = 0.882\), \(p < 0.001\)). With \(t(9) = 5.61\), we reject the null hypothesis, confirming a robust linear relationship. The 95% confidence interval (0.599, 0.969) ensures this association is both positive and substantively strong.
Prince George’s County
df %>%filter(county =="Prince George's County") %>%with(cor.test(total_grant_amount, avg_wage))
Pearson's product-moment correlation
data: total_grant_amount and avg_wage
t = 3.9199, df = 9, p-value = 0.003511
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.3709653 0.9442032
sample estimates:
cor
0.7941221
Prince George’s County also demonstrates a strong, significant positive correlation (\(r = 0.794\), \(p = 0.0035\)). With \(t(9) = 3.92\), the null hypothesis is rejected, confirming a statistically valid relationship. The 95% confidence interval (0.371, 0.944) supports this, though the wider range indicates more variability than in Montgomery County.
mont <- df %>%filter(county =="Montgomery County") %>%arrange(fiscal_year) %>%pull(avg_wage)pg <- df %>%filter(county =="Prince George's County") %>%arrange(fiscal_year) %>%pull(avg_wage)t.test(mont, pg, paired =TRUE)
Paired t-test
data: mont and pg
t = 21.031, df = 10, p-value = 1.312e-09
alternative hypothesis: true mean difference is not equal to 0
95 percent confidence interval:
16616.79 20555.03
sample estimates:
mean difference
18585.91
Interpretation Because the p-value is far below the 0.05 significance threshold, we reject the null hypothesis that the counties have equal average wages.
This indicates that, across the 2014–2024 period, Montgomery County consistently had significantly higher average wages than Prince George’s County, with an estimated average gap of approximately $18.6K per job annually.
The narrow confidence interval further suggests that this wage gap is both statistically reliable and economically meaningful.
WAGE GAP VISUALIZATION
paired_df <- df %>%select(fiscal_year, county, avg_wage) %>%pivot_wider(names_from = county, values_from = avg_wage) %>%mutate(diff =`Montgomery County`-`Prince George's County`)ggplot(paired_df, aes(x = fiscal_year, y = diff)) +geom_col(fill ="#003366") +geom_hline(yintercept =mean(paired_df$diff), linetype ="dashed", color ="red") +labs(title ="Annual Wage Gap: Montgomery vs Prince George's County",x ="Year",y ="Wage Difference ($)" ) +theme_minimal()
INTERACTIVE MARYLAND FUNDING MAP
# 1. Get Maryland counties shapefilemd_counties <-counties(state ="MD", cb =TRUE, class ="sf")
Darker counties received more total state funding.
FINAL CONCLUSION
This project found a strong and statistically significant positive relationship between Maryland state funding and county wage growth from 2014 to 2024.
Main Findings: Both counties showed strong positive correlations between grants and wages. Montgomery County had the stronger relationship, suggesting funding may align more efficiently with higher-paying sectors. Prince George’s County also showed strong results, but slightly weaker. The paired t-test confirmed Montgomery County maintained significantly higher wages throughout the study period. The funding map revealed unequal geographic concentration of taxpayer resources across Maryland. Final Interpretation:
Public investment appears connected to stronger economic outcomes, but benefits are not equally distributed. This suggests that how funding is allocated may matter just as much as how much funding is allocated.
Policy Relevance:
Maryland decision-makers can use this type of analysis to improve transparency, equity, and long-term economic impact of taxpayer spending.