A single entry point that automatically routes to the appropriate scraper
based on state. Use db_list_states("election_stats")
to see states supported by the general-election scraper.
Usage
scrape_elections(
state = NULL,
year_from = NULL,
year_to = NULL,
level = c("all", "state", "county", "precinct", "town", "parish"),
parallel = TRUE,
max_workers = 4L,
include_vote_methods = FALSE
)Arguments
- state
State name or 2-letter abbreviation, accepted in any case or spacing style (e.g.
"VA","virginia","Virginia","south_carolina","SC"). The value is normalised automatically before being passed to the underlying scraper, so callers do not need to worry about the exact format.- year_from
Start year, inclusive (default
NULL). WhenNULL, ElectionStats starts at1789; all state-portal scrapers apply no lower bound (data is clamped to each scraper's earliest confirmed year).- year_to
End year, inclusive (default
NULL). WhenNULL, the current calendar year is used as the upper bound.- level
What to return.
"all"(default) returns a named list with$state,$county, and (when available)$precinctdata frames (ElectionStats);$stateand$countydata frames (Georgia / Utah / Indiana);$stateand$towndata frames (Connecticut);$stateand$parishdata frames (Louisiana); or$precinct,$county, and$statedata frames (NC)."state"returns statewide candidate-level results only;"county"returns county vote breakdowns (ElectionStats / Georgia / Utah / Indiana);"precinct"returns precinct-level vote breakdowns — columns:state,election_id,candidate_id,county,precinct,candidate,votes(ElectionStats classic states: CO, MA, ID; v2 states: SC, NM, VA; NC viastate="NC"; Georgia and Utah — navigates county pages to find and scrape each precinct, columns:state,election_name,election_type,election_year,election_date,office_level,office,district,county,precinct,candidate,party,votes,vote_pct(write-ins are excluded, so column may not sum to 100\precinct_winner,url);"town"returns town-level results only (Connecticut);"parish"returns parish-level results only (Louisiana).- parallel
(
ElectionStats) Use parallel county scraping for classic (requests-based) states (defaultTRUE). Ignored automatically for Playwright-based states (SC, NM, NY, VA).- max_workers
(Georgia / Utah / Connecticut / Louisiana) Maximum number of parallel Chromium browsers (default
4L). For Georgia and Utah, controls county-level parallelism; for Connecticut, controls town-level parallelism; for Louisiana, controls parish-level parallelism (default is capped at 2 for LA). Ignored for all other states.- include_vote_methods
(Georgia only) If
TRUE, also return a vote-method breakdown table (Advance in Person, Election Day, Absentee by Mail, Provisional) for Georgia results (defaultFALSE). Ignored for all other states.
Value
A data.frame, or a named list when level = "all":
$state + $county (+ $precinct when available) for ElectionStats;
$state + $county + $precinct for Georgia / Utah (or just $state / $county / $precinct alone when the corresponding level is specified); $state + $county for Indiana;
$state + $town for Connecticut;
$state + $parish for Louisiana;
$precinct + $county + $state for North Carolina.
Each component is also assigned directly into the calling environment
(e.g. ga_state, ga_county) when level = "all".
Details
Routing rules (applied in order):
statematches North Carolina (e.g."NC","north_carolina") → NC State Board of Elections scraper (2000–present).statematches Connecticut (e.g."CT","connecticut") → Connecticut CTEMS scraper (2016–present).statematches Georgia (e.g."GA","georgia") → Georgia Secretary of State scraper (2000–present).statematches Utah (e.g."UT","utah") → Utah election results scraper (2023–present).statematches Indiana (e.g."IN","indiana") → Indiana General Election results scraper (2019–present).statematches Louisiana (e.g."LA","louisiana") → Louisiana Secretary of State scraper (1982–present).All other states → ElectionStats multi-state scraper.
Examples
# \donttest{
# General election results — Virginia
df <- scrape_elections(state = "virginia", year_from = 2023, year_to = 2023,
level = "state")
#> Error: Scraping failed for Virginia (ElectionStats).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# General election results — Virginia, both state and county levels
res <- scrape_elections(state = "virginia", year_from = 2023, year_to = 2023)
#> Error: Scraping failed for Virginia (ElectionStats).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
res$state # candidate-level data frame
#> Error: object 'res' not found
res$county # county vote breakdown data frame
#> Error: object 'res' not found
# North Carolina — single year
df <- scrape_elections(state = "NC", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for North Carolina (NC State Board of Elections).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Connecticut — statewide + town results for 2024
res <- scrape_elections(state = "CT", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for Connecticut (CTEMS).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
res$state # statewide totals
#> Error: object 'res' not found
res$town # town-level results
#> Error: object 'res' not found
# Connecticut — statewide only (faster; no town scraping)
df <- scrape_elections(state = "CT", year_from = 2024, year_to = 2024,
level = "state")
#> Error: Scraping failed for Connecticut (CTEMS).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Connecticut — with more parallel workers
res <- scrape_elections(state = "CT", year_from = 2022, year_to = 2022,
max_workers = 4L)
#> Error: Scraping failed for Connecticut (CTEMS).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Georgia — statewide + county results
res <- scrape_elections(state = "GA", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for Georgia (GA Secretary of State).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Georgia — statewide only (faster)
df <- scrape_elections(state = "GA", year_from = 2024, year_to = 2024,
level = "state")
#> Error: Scraping failed for Georgia (GA Secretary of State).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Georgia — with vote-method breakdown
res <- scrape_elections(state = "GA", year_from = 2024, year_to = 2024,
include_vote_methods = TRUE)
#> Error: Scraping failed for Georgia (GA Secretary of State).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Utah — statewide + county results
res <- scrape_elections(state = "UT", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for Utah (electionresults.utah.gov).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Indiana — General Election results (statewide + county)
res <- scrape_elections(state = "IN", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for Indiana (enr.indianavoters.in.gov).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
res$state # statewide candidate totals
#> Error: object 'res' not found
res$county # county-level breakdown
#> Error: object 'res' not found
# Indiana — statewide only (faster)
df <- scrape_elections(state = "IN", year_from = 2022, year_to = 2022,
level = "state")
#> Error: Scraping failed for Indiana (enr.indianavoters.in.gov).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# Louisiana — statewide + parish results
res <- scrape_elections(state = "LA", year_from = 2024, year_to = 2024)
#> Error: Scraping failed for Louisiana (voterportal.sos.la.gov).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
res$state # statewide candidate totals
#> Error: object 'res' not found
res$parish # parish-level breakdown
#> Error: object 'res' not found
# Louisiana — statewide only (faster; skips parish scraping)
df <- scrape_elections(state = "LA", year_from = 2023, year_to = 2023,
level = "state")
#> Error: Scraping failed for Louisiana (voterportal.sos.la.gov).
#>
#> Error: Python environment 'downballotR' does not exist.
#> Run downballots_install_python() first.
#>
#> If this looks like a bug or the data source may have changed,
#> please file a report (including the error above) at:
#> https://github.com/gchickering21/DownBallotR/issues
# }