get_candidate_listing <- function(years = 2016:2023) { years |> map(get_candidate_listing_year) |> bind_rows() |> type_convert( col_types = cols( election_dt = col_date(format = "%m/%d/%Y"), candidacy_dt = col_date(format = "%m/%d/%Y") ) ) |> mutate( across( contains("phone"), \(.x) sub("(\\d{3})(\\d{3})(\\d{4})", "(\\1) \\2-\\3", .x) ), across(street_address, fixup_po_box) ) |> filter(name_on_ballot != "No Preference") |> tidyr::replace_na(list( first_name = "", middle_name = "", last_name = "", name_suffix_lbl = "" )) } get_candidate_listing_year <- function(year) { url <- glue::glue("https://s3.amazonaws.com/dl.ncsbe.gov/Elections/{year}/Candidate%20Filing/Candidate_Listing_{year}.csv") read_csv( url, col_types = cols(.default = col_character()), locale = locale(encoding = "latin1") ) }