Skip to contents

geocode() geocodes addr vectors using Census TIGER address features (see ?taf) by:

  1. searching for a matching street (see ?match_addr_street), within the same ZIP code, also searching similar ZIP codes for a matching street if necessary

  2. using the address number to select the best address feature range and side of the street (even/odd), breaking ties on smallest width and spread

  3. linearly interpolating a geographic point along the best range line based on the actual and potential range of address numbers

  4. offsetting the interpolated point from the range line perpendicularly

Only matched input addresses return non-missing matched ZIP code and street values. Missing or unmatched ZIP codes return missing matched ZIP code, street, geography, and s2 cell values. If all ranges on the matched ZIP code and street exclude the address number, only the geography and s2 cell values return NA.

Usage

geocode(
  x,
  name_phonetic_dist = 1L,
  name_fuzzy_dist = 2L,
  match_street_type = c("exact", "compatible", "ignore"),
  match_street_directional = c("exact", "swap", "ignore"),
  zip_variants = TRUE,
  zip_variant = c("minus1", "plus1", "sub5", "sub4", "swap"),
  year = as.character(2025:2011),
  version = "v1",
  taf_install = TRUE,
  taf_redownload = FALSE,
  offset = 10L,
  add_s2_cell = TRUE,
  progress = interactive()
)

geocode_zip(
  x,
  offset = 10L,
  name_phonetic_dist = 1L,
  name_fuzzy_dist = 2L,
  match_street_type = c("exact", "compatible", "ignore"),
  match_street_directional = c("exact", "swap", "ignore"),
  zip_variants = TRUE,
  zip_variant = c("minus1", "plus1", "sub5", "sub4", "swap"),
  year = as.character(2025:2011),
  version = "v1",
  taf_install = TRUE,
  taf_redownload = FALSE,
  progress_callback = NULL,
  taf_check = TRUE
)

Arguments

x

an addr vector (?as_addr)

name_phonetic_dist

integer; maximum optimized string alignment distance between phonetic_street_key() of x and y to consider a possible match

name_fuzzy_dist

integer; maximum optimized string alignment distance between @name of x and y to consider a possible match

match_street_type

character; how to compare street pretype and posttype when selecting street candidates. "exact" requires pretype to match pretype and posttype to match posttype; "compatible" treats blank type fields as unknown but rejects candidates when known type information conflicts; "ignore" does not use street type fields when selecting candidates.

match_street_directional

character; how to compare street predirectional and postdirectional when selecting street candidates. "exact" requires predirectional to match predirectional and postdirectional to match postdirectional; "swap" also permits predirectional to match postdirectional and postdirectional to match predirectional; "ignore" does not use street directional fields when selecting candidates.

zip_variants

logical; fuzzy match to common variants of x in y?

zip_variant

character vector; zipcode variant types to use when zip_variants is TRUE; see ?zipcode_variant

year

integer, length one; vintage of TIGER addrfeat (address feature) files

version

character, length one; major version of the package and taf dataset schema

taf_install

logical; install missing county TAF files needed for input ZIP codes and selected ZIP code variants before geocoding? If FALSE, geocoding proceeds with installed files only and warns when needed county files are missing.

taf_redownload

logical; re-download cached TIGER ZIP files when installing missing TAF counties?

offset

number of meters to offset geocode from street line

add_s2_cell

logical; add an s2_cell column computed from matched geographies? Defaults to TRUE; set to FALSE to skip this final computation.

progress

logical; show progress messages and a ZIP-code progress bar while geocoding?

progress_callback

optional callback used internally by geocode() to update progress after ZIP-code reference data is loaded

taf_check

logical; check for missing TAF counties? Used internally by geocode() after checking once for the full input vector.

Value

A tibble with columns addr (the input addr vector), matched_zipcode (character vector), matched_street (addr_street vector), and matched_geography (s2_geography point vector). When add_s2_cell = TRUE, the tibble also includes s2_cell (s2_cell vector).

Details

geocode_zip() is the workhorse function and operates on addr vectors with the same ZIP code; use geocode() to geocode an addr vector with multiple ZIP codes by grouping them by ZIP code and processing serially by default. At a lower level, grouping addr vectors by ZIP code and applying geocode_zip() facilitates more control (e.g., parallel processing). Before ZIP grouping, geocode() deduplicates formatted addr values internally and restores the output to the original input order and length. Exact duplicates therefore do not trigger repeated TAF reads, street matching, or range interpolation, so callers usually do not need to call unique() themselves for geocoding performance.

If the mirai package is installed and mirai daemons have already been configured by the caller, geocode() uses them for ZIP-code-level parallel processing. Otherwise it falls back to sequential processing.

geocode() and geocode_zip() both download and install tiger address features by county (?taf_install) as needed based on the input addr ZIP codes (and possibly ZIP code variants). TAF install checks run before reading TAF ZIP files so parallel geocoding workers do not try to download county files at the same time.

Examples

x <- as_addr(voter_addresses()[1:25])
taf_needed_counties(x)
#> # A tibble: 335 × 7
#>    county_fips ZIP   zip3  zip2  n_ranges source_zip source_zip_variant
#>    <chr>       <chr> <chr> <chr>    <int> <chr>      <chr>             
#>  1 39061       45205 452   05         855 45205      exact             
#>  2 39061       45204 452   04         610 45205      minus1            
#>  3 39061       45206 452   06         940 45205      plus1             
#>  4 39061       45208 452   08        1217 45205      sub5              
#>  5 39061       45207 452   07         377 45205      sub5              
#>  6 39061       45204 452   04         610 45205      sub5              
#>  7 39061       45206 452   06         940 45205      sub5              
#>  8 39061       45202 452   02        2088 45205      sub5              
#>  9 39061       45203 452   03         283 45205      sub5              
#> 10 39061       45209 452   09         595 45205      sub5              
#> # ℹ 325 more rows

if (FALSE) { # \dontrun{
  # for example purposes, only install one county
  Sys.setenv("R_USER_DATA_DIR" = tempfile())
  taf_install("39061", "2025")
  # and geocode without installing other counties
  gcd <- geocode(x, taf_install = FALSE)

  # this is only for example purposes and usually not required; e.g.
  gcd <- geocode(x)

  gcd

  table(geocode_stage(gcd))

  geocode_table(gcd)

  leaflet::leaflet(wk::wk_coords(gcd$matched_geography)) |>
    leaflet::addTiles() |>
    leaflet::addCircleMarkers(lng = ~x, lat = ~y, label = ~feature_id)
} # }

if (FALSE) { # \dontrun{
  # use mirai for parallel processing
  mirai::daemons(2)
  geocode(x)
  mirai::daemons(0)
} # }