Map zip codes to their respective city and state in R?
Asked Answered
S

4

14

I have a data frame of zip codes that I'm looking to map to a city & state for each specific zip code. Currently, I have played around with the zipcode package a bit but I'm not sure that can solve this specific issue.

Here's sample data of what I have now:

str(all_key$zip)
chr [1:406] "43031" "24517" "43224" "43832" "53022" "60185" "84104" "43081" 
"85226" "85193" "54656" "43215" "94533" "95826" "64804" "49548" "54467" 

The expected output would be adding a city & state column to each row of the data frame referring to the individual zips:

 head(all_key)
     zip city  state
1   43031 city1 state1
2   24517 city2 state2
3   43224 city3 state3
4   43832 city4 state4
5   53022 city5 state5
6   60185 city6 state6

Thanks in advance for your help.

Southern answered 13/6, 2018 at 20:32 Comment(3)
Possible duplicate: #4750206Herisau
This might help: blog.exploratory.io/…Herisau
You need a crosswalk table. The problem is zip codes aren't officially standardized the way counties, etc. are, and can cross county and state lines, unlike Census geographies. Or you could do a spatial overlay of zips with cities. (Working with Census data is the bulk of my day job, so this is a familiar problem for me)Brownie
E
18

Another Update - February 2023

Another package (zipcodeR) has been added that makes this easier. See below.

Answer updated - January 2020

The zipcode package seems to have disappeared, so this answer has been updated to show how to add lat-lon from an external file. New answer at bottom.


Original answer

You can get the data from the zipcode package and just do a merge to look things up.

zip = c("43031", "24517", "43224", "43832", "53022", 
 "60185", "84104", "43081", "85226", "85193", "54656", 
 "43215", "94533", "95826", "64804", "49548", "54467")
ZC = data.frame(zip)

library(zipcode)
data(zipcode)
merge(ZC, zipcode)
     zip           city state latitude  longitude
1  24517      Altavista    VA 37.12754  -79.27409
2  43031      Johnstown    OH 40.15198  -82.66944
3  43081    Westerville    OH 40.10951  -82.91606
4  43215       Columbus    OH 39.96513  -83.00431
5  43224       Columbus    OH 40.03991  -82.96772
6  43832  Newcomerstown    OH 40.27738  -81.59662
7  49548   Grand Rapids    MI 42.86823  -85.66391
8  53022     Germantown    WI 43.21916  -88.12043
9  54467         Plover    WI 44.45228  -89.54399
10 54656         Sparta    WI 43.96977  -90.80796
11 60185   West Chicago    IL 41.89198  -88.20502
12 64804         Joplin    MO 37.04716  -94.51124
13 84104 Salt Lake City    UT 40.75063 -111.94077
14 85193    Casa Grande    AZ 32.86000 -111.83000
15 85226       Chandler    AZ 33.31221 -111.93177
16 94533      Fairfield    CA 38.26958 -122.03701
17 95826     Sacramento    CA 38.55010 -121.37492

If you need to keep the rows in the same order, you can just set the rownames on the zipcode data and use that to select the desired rows and columns.

rownames(zipcode) = zipcode$zip
zipcode[zip, 1:3]
        zip           city state
43031 43031      Johnstown    OH
24517 24517      Altavista    VA
43224 43224       Columbus    OH
43832 43832  Newcomerstown    OH
53022 53022     Germantown    WI
60185 60185   West Chicago    IL
84104 84104 Salt Lake City    UT
43081 43081    Westerville    OH
85226 85226       Chandler    AZ
85193 85193    Casa Grande    AZ
54656 54656         Sparta    WI
43215 43215       Columbus    OH
94533 94533      Fairfield    CA
95826 95826     Sacramento    CA
64804 64804         Joplin    MO
49548 49548   Grand Rapids    MI
54467 54467         Plover    WI

Updated Answer - January 2020

Since the zipcode package has disappeared, this shows how to add lat-lon information from a downloaded data set. The file that I am using exists today but the method should work for other files. See the GIS StackExchange for some leads on where to download data.

## Original Data to match
zip = c("43031", "24517", "43224", "43832", "53022", 
 "60185", "84104", "43081", "85226", "85193", "54656", 
 "43215", "94533", "95826", "64804", "49548", "54467")
ZC = data.frame(zip)

## Download source file, unzip and extract into table
ZipCodeSourceFile = "http://download.geonames.org/export/zip/US.zip"
temp <- tempfile()
download.file(ZipCodeSourceFile , temp)
ZipCodes <- read.table(unz(temp, "US.txt"), sep="\t")
unlink(temp)
names(ZipCodes) = c("CountryCode", "zip", "PlaceName", 
"AdminName1", "AdminCode1", "AdminName2", "AdminCode2", 
"AdminName3", "AdminCode3", "latitude", "longitude", "accuracy")

## merge extra info onto original data
fZC_Info = merge(ZC, ZipCodes[,c(2:6,10:11)])
head(ZC_Info)
    zip     PlaceName AdminName1 AdminCode1 AdminName2 latitude longitude
1 24517     Altavista   Virginia         VA   Campbell  37.1222  -79.2911
2 43031     Johnstown       Ohio         OH    Licking  40.1445  -82.6973
3 43081   Westerville       Ohio         OH   Franklin  40.1146  -82.9105
4 43215      Columbus       Ohio         OH   Franklin  39.9671  -83.0044
5 43224      Columbus       Ohio         OH   Franklin  40.0425  -82.9689
6 43832 Newcomerstown       Ohio         OH Tuscarawas  40.2739  -81.5940

Second Update - February 2023

Another package, zipcodeR, is now available that makes this easier. Here is some simple code to demonstrate it.

library(zipcodeR)

zip = c("43031", "24517", "43224", "43832", "53022", 
 "60185", "84104", "43081", "85226", "85193", "54656", 
 "43215", "94533", "95826", "64804", "49548", "54467")

reverse_zipcode(zip)[,c(1,3,7)]
# A tibble: 17 × 3
   zipcode major_city     state
   <chr>   <chr>          <chr>
 1 85193   Casa Grande    AZ   
 2 85226   Chandler       AZ   
 3 94533   Fairfield      CA   
 4 95826   Sacramento     CA   
 5 60185   West Chicago   IL   
 6 49548   Grand Rapids   MI   
 7 64804   Joplin         MO   
 8 43031   Johnstown      OH   
 9 43081   Westerville    OH   
10 43215   Columbus       OH   
11 43224   Columbus       OH   
12 43832   Newcomerstown  OH   
13 84104   Salt Lake City UT   
14 24517   Altavista      VA   
15 53022   Germantown     WI   
16 54467   Plover         WI   
17 54656   Sparta         WI 
Eckstein answered 13/6, 2018 at 21:3 Comment(1)
How can I do this now, given that the zipcode package has been removed from CRAN?Glochidium
P
9

You can still use the "zipcode" package by downloading it from the archives https://cran.r-project.org/src/contrib/Archive/zipcode/

Once you download the tar.gz file to your computer, you can install it from the RStudio GUI Packages pane. After clicking "Install", you can change the option to "Package Archive File" and point to the downloaded tar.gz file.

enter image description here

Pankhurst answered 2/2, 2020 at 4:39 Comment(0)
I
3

Install/use the USA package, also described here, which contains a tibble (zips and lats/longs) from the archived zipcode package.

library(usa)
zcs <- usa::zipcodes
head(zcs)

# A tibble: 6 x 5
  zip   city       state   lat  long
  <chr> <chr>      <chr> <dbl> <dbl>
1 00210 Portsmouth NH     43.0 -71.0
2 00211 Portsmouth NH     43.0 -71.0
3 00212 Portsmouth NH     43.0 -71.0
4 00213 Portsmouth NH     43.0 -71.0
5 00214 Portsmouth NH     43.0 -71.0
6 00215 Portsmouth NH     43.0 -71.0
Inocenciainoculable answered 5/11, 2020 at 14:49 Comment(0)
O
1

You can use the data frame in the R package zipcodeR.

To add the city and state to your data frame, you can select the variables you want from the data frame provided in zipcodeR (called zip_code_db), then join it with your data frame:

library(dplyr)
library(zipcodeR)

zip_code_db_selected =
  zip_code_db %>% 
  select(zipcode, major_city, state)

all_key_with_city_st = 
  left_join(all_key, zip_code_db_selected, by = c("zip" = "zipcode"))
Onieonion answered 25/2, 2021 at 4:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.