Skip to contents

A single entry point that automatically routes to the appropriate scraper based on state and office. Use db_list_states("election_stats") to see states supported by the general-election scraper.

Usage

scrape_elections(
  state = NULL,
  office = c("general", "school_district", "state_elections", "municipal_elections"),
  year_from = NULL,
  year_to = NULL,
  level = c("all", "state", "county", "joined", "town"),
  parallel = TRUE,
  year = NULL,
  mode = c("districts", "results", "joined", "listings", "links"),
  start_year = NULL,
  end_year = NULL,
  election_level = c("all", "federal", "state", "local"),
  race_type = c("all", "mayoral"),
  max_county_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. Pass NULL to return all states (Ballotpedia scrapers only).

office

Type of election to retrieve. "general" (default) fetches general election results via ElectionStats or the NC scraper; "school_district" fetches school board elections via Ballotpedia; "state_elections" fetches federal, state, and local candidate listings from Ballotpedia state election pages (2024–present); "municipal_elections" fetches city, county, and mayoral election data from Ballotpedia municipal election index pages (2014–present).

year_from

(general / NC) Start year, inclusive (default NULL). When NULL, ElectionStats starts at 1789; the NC scraper applies no lower bound.

year_to

(general / NC) End year, inclusive (default NULL). When NULL, ElectionStats uses the current calendar year; the NC scraper applies no upper bound.

level

(general / ElectionStats / Connecticut / Georgia) What to return. "all" (default) returns a named list with $state and $county data frames (ElectionStats / Georgia), or $state and $town data frames (Connecticut); "state" returns statewide candidate-level results only; "county" returns county vote breakdowns (ElectionStats / Georgia); "town" returns town-level results only (Connecticut); "joined" returns county rows merged with candidate metadata (ElectionStats only).

parallel

(general / ElectionStats) Use parallel county scraping for classic (requests-based) states (default TRUE). Ignored automatically for Playwright-based states (SC, NM, NY).

year

(school_district) Election year (e.g. 2024). Required when mode = "results" or mode = "joined". If NULL with mode = "districts", use start_year / end_year for a multi-year scrape.

mode

(school_district) What to return. "districts" (default) returns fast district metadata (one request per year-page); "results" follows each district URL for candidate/vote data; "joined" returns districts and candidates merged into one data frame. For state_elections: "listings" (default) returns one row per candidate from the state+year page (fast); "results" additionally follows each contest URL for vote counts (slower). For municipal_elections: "links" (default) returns index discovery only — one row per election sub-URL with location metadata but no vote data (fast); "results" follows each sub-URL for full candidate and vote data (slower).

start_year

(school_district) Earliest year for a multi-year district scrape when year is NULL (default 2013). For state_elections, earliest year when year is NULL (default 2024). For municipal_elections, earliest year when year is NULL (default 2014).

end_year

(school_district / state_elections / municipal_elections) Latest year for a multi-year scrape when year is NULL (default: current calendar year).

election_level

(state_elections) Which candidate tier to return. "all" (default) returns all tiers; "federal" returns U.S. House / Senate / Presidential Electors only; "state" returns state-level races only; "local" returns local races only.

race_type

(municipal_elections) Which index page to use. "all" (default) uses the broader United_States_municipal_elections page (2014–present), covering city, county, and mayoral races. "mayoral" uses the United_States_mayoral_elections page (2020–present), covering only mayoral races.

max_county_workers

(general / Georgia / Connecticut) Maximum number of parallel Chromium browsers. For Georgia, controls county-level parallelism (default 4L); for Connecticut, controls town-level parallelism (default 2L). Ignored for all other states.

include_vote_methods

(general / Georgia) If TRUE, also return a vote-method breakdown table (Advance in Person, Election Day, Absentee by Mail, Provisional) for Georgia results (default FALSE). Ignored for all other states.

Value

A data.frame, or a named list when level = "all": $state + $county for ElectionStats / Georgia; $state + $town for Connecticut. NC and state-elections always return a single data.frame.

Details

Routing rules (applied in order):

  1. office = "school_district" → Ballotpedia school board scraper (all US states; use state to filter to one state).

  2. office = "state_elections" → Ballotpedia state elections scraper (federal, state, and local candidates; 2024–present).

  3. office = "municipal_elections" → Ballotpedia municipal and mayoral elections scraper (all US states, 2014–present).

  4. state matches North Carolina (e.g. "NC", "north_carolina") → NC State Board of Elections scraper.

  5. state matches Connecticut (e.g. "CT", "connecticut") → Connecticut CTEMS scraper (2000–present).

  6. state matches Georgia (e.g. "GA", "georgia") → Georgia Secretary of State scraper (2012–present).

  7. All other states → ElectionStats multi-state scraper.

Examples

if (FALSE) { # \dontrun{
# General election results — Virginia
df <- scrape_elections(state = "virginia", year_from = 2023, year_to = 2023,
                       level = "state")

# General election results — Virginia, both state and county levels
res <- scrape_elections(state = "virginia", year_from = 2023, year_to = 2023)
res$state   # candidate-level data frame
res$county  # county vote breakdown data frame

# North Carolina — single year
df <- scrape_elections(state = "NC", year_from = 2024, year_to = 2024)

# North Carolina — multi-year range
df <- scrape_elections(state = "NC", year_from = 2022, year_to = 2024)

# School district elections — one state, one year (fast district metadata)
df <- scrape_elections(state = "Alabama", office = "school_district",
                       year = 2024)

# School district elections — all states, multi-year
df <- scrape_elections(office = "school_district",
                       start_year = 2020, end_year = 2024)

# State elections — candidate listings (fast, no vote counts)
df <- scrape_elections(state = "Maine", office = "state_elections",
                       year = 2024)

# State elections — federal candidates only
df <- scrape_elections(state = "Pennsylvania", office = "state_elections",
                       year = 2024, election_level = "federal")

# State elections — full results with vote counts (follows contest links)
df <- scrape_elections(state = "Maine", office = "state_elections",
                       year = 2024, mode = "results")

# Municipal elections — index links only (fast, no vote data)
df <- scrape_elections(office = "municipal_elections", year = 2022,
                       state = "Texas")

# Municipal elections — mayoral only, full candidate results
df <- scrape_elections(office = "municipal_elections", year = 2022,
                       race_type = "mayoral", mode = "results")

# Municipal elections — multi-year index links
df <- scrape_elections(office = "municipal_elections",
                       start_year = 2020, end_year = 2022,
                       race_type = "all")

# Connecticut — statewide + town results for 2024
res <- scrape_elections(state = "CT", year_from = 2024, year_to = 2024)
res$state  # statewide totals (Federal from Summary + State/Local aggregated from towns)
res$town   # town-level results for every town

# Connecticut — statewide only (faster; no town scraping)
df <- scrape_elections(state = "CT", year_from = 2024, year_to = 2024,
                       level = "state")

# Connecticut — town-level results only
df <- scrape_elections(state = "CT", year_from = 2024, year_to = 2024,
                       level = "town")

# Connecticut — specific election year with extra parallel workers
res <- scrape_elections(state = "connecticut", year_from = 2022, year_to = 2022,
                        max_county_workers = 4L)
} # }