Fetch and analyze Alaska school enrollment data from the Alaska Department of Education and Early Development (DEED) in R or Python. 126,000 students across 53 districts in America’s largest and most remote state.
Part of the njschooldata family.
Full documentation — all 15 stories with interactive charts, getting-started guide, and complete function reference.
Highlights
library(akschooldata)
library(dplyr)
library(tidyr)
library(ggplot2)
theme_set(theme_minimal(base_size = 14))
# Get available year range from package
available <- get_available_years()
min_year <- available$min_year
max_year <- available$max_year
all_years <- min_year:max_year
enr <- fetch_enr_multi(all_years, use_cache = TRUE)
enr_latest <- fetch_enr(max_year, use_cache = TRUE)1. One in six Alaska students is in a correspondence program
Correspondence and distance education schools serve over 20,000 students–about 16.5% of total statewide enrollment. These programs surged to 22,341 students in 2021, dropped during post-pandemic normalization, and are climbing again.
state_annual <- enr |>
filter(is_state, subgroup == "total_enrollment", grade_level == "TOTAL") |>
select(end_year, state_total = n_students)
corr_by_year <- enr |>
filter(is_campus, subgroup == "total_enrollment", grade_level == "TOTAL") |>
filter(grepl("IDEA|Correspondence|Distance|Central School|Raven|Cyber|Connections|PEAK|REACH|SAVE|PACE", campus_name, ignore.case = TRUE)) |>
group_by(end_year) |>
summarize(
n_programs = n(),
corr_students = sum(n_students),
.groups = "drop"
) |>
left_join(state_annual, by = "end_year") |>
mutate(pct_of_state = round(corr_students / state_total * 100, 1))
stopifnot(nrow(corr_by_year) > 0)
print(corr_by_year)
#> # A tibble: 5 x 5
#> end_year n_programs corr_students state_total pct_of_state
#> <int> <int> <dbl> <dbl> <dbl>
#> 1 2021 20 22341 127210 17.6
#> 2 2022 22 17884 127509 14
#> 3 2023 22 17160 128088 13.4
#> 4 2024 23 19782 127931 15.5
#> 5 2025 24 20882 126284 16.5
2. Kindergarten is dropping while 12th grade grows
Kindergarten enrollment fell from 9,790 in 2022 to 8,869 in 2025, while 12th grade grew from 9,455 to 9,984 over the same period. The pipeline is getting thinner at the bottom.
grade_trends <- enr |>
filter(is_state, subgroup == "total_enrollment",
grade_level %in% c("K", "12")) |>
select(end_year, grade_level, n_students) |>
pivot_wider(names_from = grade_level, values_from = n_students)
stopifnot(nrow(grade_trends) > 0)
print(grade_trends)
#> # A tibble: 5 x 3
#> end_year K `12`
#> <int> <dbl> <dbl>
#> 1 2021 9412 9504
#> 2 2022 9790 9455
#> 3 2023 9650 9647
#> 4 2024 9257 9765
#> 5 2025 8869 9984
3. Twelve students, one district
Pelican City School District serves just 12 students–but under Alaska law, it still operates as a full district. Nine districts have fewer than 135 students each.
micro_districts <- enr_latest |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
filter(n_students < 150) |>
arrange(n_students) |>
select(district_name, n_students) |>
head(10)
stopifnot(nrow(micro_districts) > 0)
print(micro_districts)
#> district_name n_students
#> 1 Pelican City School District 12
#> 2 Aleutian Region School District 21
#> 3 Pribilof School District 60
#> 4 Yakutat School District 94
#> 5 Bristol Bay Borough School District 101
#> 6 Hydaburg City School District 108
#> 7 Hoonah City School District 109
#> 8 Kake City School District 111
#> 9 Klawock City School District 124
#> 10 Skagway School District 133
Data Taxonomy
| Category | Years | Function | Details |
|---|---|---|---|
| Enrollment | 2021-2025 |
fetch_enr() / fetch_enr_multi()
|
State, district (~53), campus (~488). Subgroups: total_enrollment, white, black, hispanic, asian, native_american, pacific_islander, multiracial, male, female. Grades: PK, K, 01-12, UG, TOTAL. Flags: is_state, is_district, is_campus, is_charter. |
| Assessments | – | – | Not yet available |
| Graduation | – | – | Not yet available |
| Directory | Current | fetch_directory() |
All schools (~500+). District, community, type, website, coordinates. Open/closed status. |
| Per-Pupil Spending | – | – | Not yet available |
| Accountability | – | – | Not yet available |
| Chronic Absence | – | – | Not yet available |
| EL Progress | – | – | Not yet available |
| Special Ed | – | – | Not yet available |
See DATA-CATEGORY-TAXONOMY.md for what each category covers.
Quick Start
Installation
# install.packages("remotes")
remotes::install_github("almartin82/akschooldata")R
library(akschooldata)
library(dplyr)
# Fetch one year
enr_2025 <- fetch_enr(2025)
# Fetch multiple years
enr_multi <- fetch_enr_multi(2021:2025)
# State totals
enr_2025 |>
filter(is_state, subgroup == "total_enrollment", grade_level == "TOTAL")
# District breakdown
enr_2025 |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
arrange(desc(n_students))Python
import pyakschooldata as ak
# Fetch one year
enr_2025 = ak.fetch_enr(2025)
# Fetch multiple years
enr_multi = ak.fetch_enr_multi([2021, 2022, 2023, 2024, 2025])
# State totals
state_totals = enr_2025[
(enr_2025['is_state'] == True) &
(enr_2025['subgroup'] == 'total_enrollment') &
(enr_2025['grade_level'] == 'TOTAL')
]
# District breakdown
districts = enr_2025[
(enr_2025['is_district'] == True) &
(enr_2025['subgroup'] == 'total_enrollment') &
(enr_2025['grade_level'] == 'TOTAL')
].sort_values('n_students', ascending=False)Data Notes
| Years | Source | Notes |
|---|---|---|
| 2021-2025 | DEED October 1 Count | Grade-level enrollment by school |
Data is sourced directly from the Alaska Department of Education and Early Development (DEED).
What’s included
- Levels: State, district (~53), school (~488)
- Grade levels: Pre-K through 12
- Note: Demographic breakdowns (race/ethnicity) are downloaded from DEED but not yet available in the tidy output
Caveats
- Gender breakdowns not available in DEED files
- Small cell sizes may be suppressed for privacy
- Charter schools are operated by traditional districts
- District names changed between 2023 and 2024 in DEED files (e.g., “Anchorage Schools” became “Anchorage School District”)
Data source
Alaska Department of Education and Early Development: Data Center
Deeper Dive
4. Alaska enrollment peaked in 2023, then dropped
Alaska’s public school enrollment rose from 127,210 in 2021 to 128,088 in 2023 before falling sharply to 126,284 in 2025–a net loss of nearly 1,000 students in five years.
enr <- fetch_enr_multi(all_years, use_cache = TRUE)
state_totals <- enr |>
filter(is_state, subgroup == "total_enrollment", grade_level == "TOTAL") |>
select(end_year, n_students) |>
mutate(change = n_students - lag(n_students),
pct_change = round(change / lag(n_students) * 100, 2))
stopifnot(nrow(state_totals) > 0)
print(state_totals)
#> end_year n_students change pct_change
#> 1 2021 127210 NA NA
#> 2 2022 127509 299 0.24
#> 3 2023 128088 579 0.45
#> 4 2024 127931 -157 -0.12
#> 5 2025 126284 -1647 -1.29
5. Anchorage is a third of the state
The Anchorage School District educates about a third of all Alaska students–41,598 out of 126,284 statewide. Galena, home to the IDEA correspondence program, is the surprising #5.
enr_latest <- fetch_enr(max_year, use_cache = TRUE)
top_districts <- enr_latest |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
arrange(desc(n_students)) |>
head(10) |>
select(district_name, n_students)
stopifnot(nrow(top_districts) > 0)
print(top_districts)
#> district_name n_students
#> 1 Anchorage School District 41598
#> 2 Matanuska-Susitna Borough School District 19019
#> 3 Fairbanks North Star Borough School District 11707
#> 4 Kenai Peninsula Borough School District 8355
#> 5 Galena City School District 7839
#> 6 Yukon-Koyukuk School District 3930
#> 7 Juneau Borough School District 3923
#> 8 Lower Kuskokwim School District 3680
#> 9 Nenana City School District 2196
#> 10 Kodiak Island Borough School District 2049
6. Post-COVID enrollment shocks hit correspondence programs hardest
Between 2021 and 2022, the biggest enrollment drops were in correspondence-heavy districts: Hydaburg fell 24.9%, Yukon-Koyukuk 19.9%, and Galena (home to IDEA) 19.4%.
# Compare 2021 to 2022
covid_years <- 2021:2022
post_covid_enr <- fetch_enr_multi(covid_years, use_cache = TRUE)
covid_changes <- post_covid_enr |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL",
end_year %in% covid_years) |>
select(district_name, end_year, n_students) |>
pivot_wider(names_from = end_year, values_from = n_students, names_prefix = "y") |>
mutate(pct_change = round((y2022 / y2021 - 1) * 100, 1)) |>
arrange(pct_change) |>
head(10) |>
select(district_name, y2021, y2022, pct_change)
stopifnot(nrow(covid_changes) > 0)
print(covid_changes)
#> # A tibble: 10 x 4
#> district_name y2021 y2022 pct_change
#> <chr> <dbl> <dbl> <dbl>
#> 1 Hydaburg City Schools 169 127 -24.9
#> 2 Yukon-Koyukuk Schools 4160 3332 -19.9
#> 3 Galena City Schools 9030 7276 -19.4
#> 4 Craig City Schools 874 713 -18.4
#> 5 Tanana Schools 30 26 -13.3
#> 6 Denali Borough Schools 1152 1003 -12.9
#> 7 Yupiit Schools 506 444 -12.3
#> 8 Nenana City Schools 1843 1633 -11.4
#> 9 Bristol Bay Borough Schools 119 106 -10.9
#> 10 Iditarod Area Schools 322 288 -10.67. Mat-Su grew while Anchorage fluctuated
The Matanuska-Susitna Borough School District (Palmer/Wasilla area) grew from 17,935 to 19,019 students between 2021 and 2025, while Anchorage’s numbers rose and fell with no clear direction.
matsu <- enr |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL",
grepl("Mat-Su|Matanuska", district_name, ignore.case = TRUE)) |>
select(end_year, district_name, n_students)
stopifnot(nrow(matsu) > 0)
print(matsu)
#> end_year district_name n_students
#> 1 2021 Mat-Su Borough Schools 17935
#> 2 2022 Mat-Su Borough Schools 18957
#> 3 2023 Mat-Su Borough Schools 19225
#> 4 2024 Matanuska-Susitna Borough School District 19271
#> 5 2025 Matanuska-Susitna Borough School District 19019
8. Fifteen districts have fewer than 200 students
Fifteen Alaska districts serve fewer than 200 students each. The smallest, Pelican City School District, has just 12 students. These tiny districts face unique challenges in America’s most remote state.
small_districts <- enr_latest |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
filter(n_students < 200) |>
arrange(n_students) |>
select(district_name, n_students)
stopifnot(nrow(small_districts) > 0)
print(small_districts)
#> district_name n_students
#> 1 Pelican City School District 12
#> 2 Aleutian Region School District 21
#> 3 Pribilof School District 60
#> 4 Yakutat School District 94
#> 5 Bristol Bay Borough School District 101
#> 6 Hydaburg City School District 108
#> 7 Hoonah City School District 109
#> 8 Kake City School District 111
#> 9 Klawock City School District 124
#> 10 Skagway School District 133
#> 11 Chatham School District 161
#> 12 Saint Mary's School District 161
#> 13 Aleutians East Borough School District 163
#> 14 Southeast Island School District 164
#> 15 Yukon Flats School District 1719. The graduation pipeline leaks in rural districts
The ratio of 12th graders to 9th graders reveals where students are leaving before graduation. Nome retains just 48.5% and Southwest Region 52.8%, while urban districts like Kodiak actually gain students.
pipeline <- enr_latest |>
filter(is_district, subgroup == "total_enrollment",
grade_level %in% c("09", "12")) |>
select(district_name, grade_level, n_students) |>
pivot_wider(names_from = grade_level, values_from = n_students) |>
mutate(ratio = round(`12` / `09` * 100, 1)) |>
filter(`09` >= 50) |>
arrange(ratio) |>
head(10) |>
select(district_name, `09`, `12`, ratio)
stopifnot(nrow(pipeline) > 0)
print(pipeline)
#> # A tibble: 10 x 4
#> district_name `09` `12` ratio
#> <chr> <dbl> <dbl> <dbl>
#> 1 Nome Public Schools 68 33 48.5
#> 2 Southwest Region School District 53 28 52.8
#> 3 Delta/Greely School District 85 56 65.9
#> 4 Lower Kuskokwim School District 339 242 71.4
#> 5 Bering Strait School District 140 120 85.7
#> 6 Mount Edgecumbe 104 94 90.4
#> 7 Matanuska-Susitna Borough School District 1446 1365 94.4
#> 8 Fairbanks North Star Borough School District 846 827 97.8
#> 9 Kenai Peninsula Borough School District 673 661 98.2
#> 10 Kodiak Island Borough School District 172 175 102.10. Anchorage and Fairbanks both grew, then contracted
Both Anchorage and Fairbanks saw enrollment rise from 2021 to 2023 before falling back. Fairbanks peaked at 112.2% of its 2021 level in 2023, then dropped to 104.5% by 2025.
major_districts <- enr |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL",
grepl("Fairbanks|Anchorage", district_name)) |>
mutate(district_simple = case_when(
grepl("Anchorage", district_name) ~ "Anchorage",
grepl("Fairbanks", district_name) ~ "Fairbanks",
TRUE ~ district_name
)) |>
group_by(district_simple) |>
mutate(index = round(n_students / first(n_students) * 100, 1)) |>
select(end_year, district_simple, n_students, index)
stopifnot(nrow(major_districts) > 0)
print(major_districts)
#> # A tibble: 10 x 4
#> # Groups: district_simple [2]
#> end_year district_simple n_students index
#> <int> <chr> <dbl> <dbl>
#> 1 2021 Anchorage 41203 100
#> 2 2021 Fairbanks 11199 100
#> 3 2022 Anchorage 42701 103.6
#> 4 2022 Fairbanks 12199 108.9
#> 5 2023 Anchorage 43325 105.2
#> 6 2023 Fairbanks 12568 112.2
#> 7 2024 Anchorage 42431 103
#> 8 2024 Fairbanks 12365 110.4
#> 9 2025 Anchorage 41598 101
#> 10 2025 Fairbanks 11707 104.5
11. Alaska’s geography creates unique schools
Some Alaska schools are only accessible by plane or boat. The 10 smallest districts collectively serve fewer than 1,000 students across areas larger than many states.
smallest <- enr_latest |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
arrange(n_students) |>
head(10) |>
select(district_name, n_students)
stopifnot(nrow(smallest) > 0)
print(smallest)
#> district_name n_students
#> 1 Pelican City School District 12
#> 2 Aleutian Region School District 21
#> 3 Pribilof School District 60
#> 4 Yakutat School District 94
#> 5 Bristol Bay Borough School District 101
#> 6 Hydaburg City School District 108
#> 7 Hoonah City School District 109
#> 8 Kake City School District 111
#> 9 Klawock City School District 124
#> 10 Skagway School District 13312. IDEA serves more students than all but four districts
Alaska pioneered distance education out of necessity. Interior Distance Education of Alaska (IDEA) alone enrolls 7,564 students, making its parent district (Galena) the 5th largest in the state. Raven School adds another 3,603.
distance_schools <- enr_latest |>
filter(is_campus, subgroup == "total_enrollment", grade_level == "TOTAL") |>
filter(grepl("IDEA|Correspondence|Distance|Central School|Raven|Cyber|Connections|PEAK|REACH|SAVE|PACE", campus_name, ignore.case = TRUE)) |>
arrange(desc(n_students)) |>
head(10) |>
select(district_name, campus_name, n_students)
stopifnot(nrow(distance_schools) > 0)
print(distance_schools)
#> district_name
#> 1 Galena City School District
#> 2 Yukon-Koyukuk School District
#> 3 Matanuska-Susitna Borough School District
#> 4 Nenana City School District
#> 5 Kenai Peninsula Borough School District
#> 6 Anchorage School District
#> 7 Craig City School District
#> 8 Anchorage School District
#> 9 Copper River School District
#> 10 Iditarod Area School District
#> campus_name n_students
#> 1 Interior Distance Education of Alaska (IDEA) 7564
#> 2 Raven School 3603
#> 3 Mat-Su Central School 2780
#> 4 CyberLynx Correspondence Program 2002
#> 5 Connections 1144
#> 6 Family Partnership Correspondence School 1008
#> 7 PACE Correspondence 414
#> 8 Ravenwood Elementary 345
#> 9 Upstream Learning Correspondence 111
#> 10 Distance Learning/Corresp. Ctr. 105
13. Pre-K crashed 16.8% in 2022, then rebounded
Pre-Kindergarten enrollment plummeted from 3,526 to 2,933 between 2021 and 2022–a 16.8% drop. It has since recovered to 3,619 in 2025, surpassing its pre-pandemic level.
prek_trend <- enr |>
filter(is_state, subgroup == "total_enrollment", grade_level == "PK") |>
select(end_year, n_students) |>
mutate(change = n_students - lag(n_students),
pct_change = round(change / lag(n_students) * 100, 1))
stopifnot(nrow(prek_trend) > 0)
print(prek_trend)
#> end_year n_students change pct_change
#> 1 2021 3526 NA NA
#> 2 2022 2933 -593 -16.8
#> 3 2023 3124 191 6.5
#> 4 2024 3333 209 6.7
#> 5 2025 3619 286 8.6
14. Elementary shrinks while high school holds steady
Elementary enrollment (K-5) fell from 58,923 to 57,282 between 2021 and 2025, while high school (9-12) actually grew from 38,168 to 39,598. Smaller incoming cohorts haven’t reached high school yet.
level_trends <- enr |>
filter(is_state, subgroup == "total_enrollment") |>
mutate(level = case_when(
grade_level %in% c("K", "01", "02", "03", "04", "05") ~ "Elementary (K-5)",
grade_level %in% c("06", "07", "08") ~ "Middle (6-8)",
grade_level %in% c("09", "10", "11", "12") ~ "High School (9-12)",
TRUE ~ NA_character_
)) |>
filter(!is.na(level)) |>
group_by(end_year, level) |>
summarize(n_students = sum(n_students), .groups = "drop")
stopifnot(nrow(level_trends) > 0)
print(level_trends)
#> # A tibble: 15 x 3
#> end_year level n_students
#> <int> <chr> <dbl>
#> 1 2021 Elementary (K-5) 58923
#> 2 2021 High School (9-12) 38168
#> 3 2021 Middle (6-8) 30119
#> 4 2022 Elementary (K-5) 58895
#> 5 2022 High School (9-12) 38615
#> 6 2022 Middle (6-8) 29999
#> 7 2023 Elementary (K-5) 59000
#> 8 2023 High School (9-12) 39219
#> 9 2023 Middle (6-8) 29869
#> 10 2024 Elementary (K-5) 58554
#> 11 2024 High School (9-12) 39776
#> 12 2024 Middle (6-8) 29601
#> 13 2025 Elementary (K-5) 57282
#> 14 2025 High School (9-12) 39598
#> 15 2025 Middle (6-8) 29404
15. REAAs and other non-borough districts serve the most students
Alaska’s 27 “other” districts (REAAs, correspondence-heavy districts, and Mt. Edgecumbe) collectively serve 60,644 students–more than the 14 borough districts combined (52,889).
dist_types <- enr_latest |>
filter(is_district, subgroup == "total_enrollment", grade_level == "TOTAL") |>
mutate(dist_type = case_when(
grepl("Borough", district_name) ~ "Borough District",
grepl("City", district_name) ~ "City District",
TRUE ~ "Other (REAAs, etc.)"
)) |>
group_by(dist_type) |>
summarize(
n_districts = n(),
total_students = sum(n_students),
.groups = "drop"
) |>
mutate(avg_students = round(total_students / n_districts))
stopifnot(nrow(dist_types) > 0)
print(dist_types)
#> # A tibble: 3 x 4
#> dist_type n_districts total_students avg_students
#> <chr> <int> <dbl> <dbl>
#> 1 Borough District 14 52889 3778
#> 2 City District 12 12751 1063
#> 3 Other (REAAs, etc.) 27 60644 2246