What it covers
The ElectionStats scraper pulls candidate-level and county-level election results from state-hosted ElectionStats sites.
| State | Backend | Start year | End year |
|---|---|---|---|
| Vermont | Classic (requests) | 1789 | 2024 |
| Virginia | Classic (requests) | 1789 | 2025 |
| Colorado | Classic (requests) | 1902 | 2024 |
| Massachusetts | Classic (requests) | 1970 | 2026 |
| New Hampshire | Classic (requests) | 1970 | 2024 |
| New York | v2 (Playwright) | 1994 | 2024 |
| New Mexico | v2 (Playwright) | 2000 | 2024 |
| South Carolina | v2 (Playwright) | 2008 | 2025 |
Classic states use simple HTTP requests and are fast. Playwright states (NY, NM, SC) launch a headless Chromium browser to render JavaScript — they are slower but fully automated.
Arguments
| Argument | Default | Description |
|---|---|---|
state |
required | State name, snake_case (e.g. "virginia") |
year_from |
NULL (earliest) |
Start year, inclusive |
year_to |
NULL (current year) |
End year, inclusive |
level |
"all" |
What to return — see below |
parallel |
TRUE |
Parallel county scraping (classic states only) |
Examples
Candidate-level results for a single year
state_df <- scrape_elections(
state = "virginia",
year_from = 2023,
year_to = 2023,
level = "state"
)
state_df %>%
filter(contest_outcome == "Winner") %>%
arrange(desc(total_vote_count)) %>%
select(office, district, candidate, party, total_vote_count)County-level vote counts
county_df <- scrape_elections(
state = "virginia",
year_from = 2023,
year_to = 2023,
level = "county"
)
county_df %>%
arrange(desc(votes)) %>%
select(county_or_city, candidate_name, votes)Both levels at once (default)
level = "all" returns a named list with
$state and $county elements:
res <- scrape_elections(
state = "virginia",
year_from = 2023,
year_to = 2023
)
res$state # candidate-level data frame
res$county # county breakdown data frameMulti-year range
ma_results <- scrape_elections(
state = "massachusetts",
year_from = 2018,
year_to = 2022,
level = "state"
)
ma_results %>%
filter(stage == "General") %>%
select(year, office, district, candidate, party, total_vote_count)Playwright state (South Carolina)
sc_results <- scrape_elections(
state = "south_carolina",
year_from = 2024,
year_to = 2024,
level = "state"
)
sc_results %>%
filter(contest_outcome == "Winner") %>%
select(office, district, candidate, party, vote_percentage)Joined data (county + candidate metadata)
joined <- scrape_elections(
state = "virginia",
year_from = 2023,
year_to = 2023,
level = "joined"
)
joined %>%
select(county_or_city, office, candidate, party, votes)Disable parallel scraping
res_seq <- scrape_elections(
state = "virginia",
year_from = 2023,
year_to = 2023,
level = "joined",
parallel = FALSE
)