The edfinr package provides tidy, analysis-ready school
district finance data for the United States — NCES F-33 revenues and
expenditures joined with enrollment, poverty, community, and labor-cost
measures — assembled with an opinionated cleaning methodology. This
vignette will help you get started with the package’s core
functionality.
The primary function in edfinr is
get_finance_data(), which provides access to school finance
data from school years 2011-12 through 2022-23. NCES F-33 data are
released roughly two years after a fiscal year closes, so FY2023
(SY2022-23) is the most recent federal release. The function combines
data from multiple sources:
The simplest way to use get_finance_data() is to specify
a year and state. For example, to get finance data for Kentucky school
districts from the 2022-23 school year:
By default, get_finance_data() returns a “skinny”
dataset with 59 essential variables covering:
exp_cap_total, exp_cap_total_pp).land_area_sq_mi, s_per_sq_mi).For more detailed analysis, you can request the “full” dataset with 124 variables that includes:
With 124 variables in the full dataset, the data dictionary is the
fastest way to find what you need. list_variables() returns
it as a tibble, so you can filter and search it like any other data.
## # A tibble: 124 × 7
## name type category source f33_item first_yr_avail description
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 ncesid character id NCES … LEAID 2012 NCES distr…
## 2 year integer time NCES … YRDATA 2012 School yea…
## 3 state character geographic NCES … STATE 2012 State abbr…
## 4 dist_name character id NCES … NAME 2012 District n…
## 5 enroll numeric demographic NCES … V33 2012 Total dist…
## 6 rev_total_pp numeric revenue NCES … <NA> 2012 Total adju…
## 7 rev_local_pp numeric revenue NCES … <NA> 2012 Local adju…
## 8 rev_state_pp numeric revenue NCES … <NA> 2012 State adju…
## 9 rev_fed_pp numeric revenue NCES … <NA> 2012 Federal ad…
## 10 rev_total numeric revenue NCES … <NA> 2012 Total adju…
## # ℹ 114 more rows
## # A tibble: 9 × 7
## name type category source f33_item first_yr_avail description
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 debt_lt_begin numeric debt NCES F… _19H 2012 Long-term …
## 2 debt_lt_issued numeric debt NCES F… _21F 2012 Long-term …
## 3 debt_lt_retired numeric debt NCES F… _31F 2012 Long-term …
## 4 debt_lt_end numeric debt NCES F… _41F 2012 Long-term …
## 5 debt_st_begin numeric debt NCES F… _61V 2012 Short-term…
## 6 debt_st_end numeric debt NCES F… _66V 2012 Short-term…
## 7 fund_bal_debt_svc numeric debt NCES F… W01 2012 Debt servi…
## 8 fund_bal_bond numeric debt NCES F… W31 2012 Bond fund …
## 9 fund_bal_other numeric debt NCES F… W61 2012 Other fund…
The get_finance_data() function makes it easy to access
data across multiple years and states:
Only the requested year(s) are downloaded: each year is hosted as its
own file (roughly 3-6 MB), so a single-year or short-range request is
lightweight even though the full panel spans 2012-2023. Requesting
yr = "all" downloads the entire history from one combined
file.
Downloaded files are cached in R’s temporary directory for the length
of your R session, so repeated calls with the same years re-read the
cache instead of re-downloading. Two arguments control this behavior:
refresh = TRUE forces a fresh download (for example, after
a data update is announced), and quiet = TRUE suppresses
the download progress messages.
Once you’ve retrieved the data, you can use standard data manipulation tools to analyze it. Here are some common analysis patterns:
# compare revenue mix across urbanicity groups (dollar-weighted)
revenue_analysis <- ct_sy23 |>
group_by(urbanicity) |>
summarize(
pct_local = sum(rev_local, na.rm = TRUE) / sum(rev_total, na.rm = TRUE),
pct_state = sum(rev_state, na.rm = TRUE) / sum(rev_total, na.rm = TRUE),
pct_federal = sum(rev_fed, na.rm = TRUE) / sum(rev_total, na.rm = TRUE),
n_districts = n(),
enrollment = sum(enroll, na.rm = TRUE)
)
revenue_analysis