State name to abbreviation

R

R Problem Overview


I have a large file with a variable state that has full state names. I would like to replace it with the state abbreviations (that is "NY" for "New York"). Is there an easy way to do this (apart from using several if-else commands)? May be using replace() statement?

R Solutions


Solution 1 - R

R has two built-in constants that might help: state.abb with the abbreviations, and state.name with the full names. Here is a simple usage example:

> x <- c("New York", "Virginia")
> state.abb[match(x,state.name)]
[1] "NY" "VA"

Solution 2 - R

1) grep the full name from state.name and use that to index into state.abb:

state.abb[grep("New York", state.name)]
## [1] "NY"

1a) or using which:

state.abb[which(state.name == "New York")]
## [1] "NY"

2) or create a vector of state abbreviations whose names are the full names and index into it using the full name:

setNames(state.abb, state.name)["New York"]
## New York 
##     "NY" 

Unlike (1), this one works even if "New York" is replaced by a vector of full state names, e.g. setNames(state.abb, state.name)[c("New York", "Idaho")]

Solution 3 - R

I found the built-in state.name and state.abb have only 50 states. I got a bigger table (including DC and so on) from online (e.g., this link: http://www.infoplease.com/ipa/A0110468.html) and pasted it to a .csv file named States.csv. I then load states and abbr. from this file instead of using the built-in. The rest is quite similar to @Aniko 's

library(dplyr)
library(stringr)
library(stringdist)

setwd()
# load data
data = c("NY", "New York", "NewYork")
data = toupper(data)

# load state name and abbr.
State.data = read.csv('States.csv')
State = toupper(State.data$State)
Stateabb = as.vector(State.data$Abb)

# match data with state names, misspell of 1 letter is allowed
match = amatch(data, State, maxDist=1)
data[ !is.na(match) ] = Stateabb[ na.omit( match ) ]

There's a small difference between match and amatch in how they calculate the distance from one word to another. See P25-26 here http://cran.r-project.org/doc/contrib/de_Jonge+van_der_Loo-Introduction_to_data_cleaning_with_R.pdf

Solution 4 - R

Old post I know, but wanted to throw mine in there. I learned on tidyverse, so for better or worse I avoid base R when possible. I wanted one with DC too, so first I built the crosswalk:

library(tidyverse)

 st_crosswalk <- tibble(state = state.name) %>%
   bind_cols(tibble(abb = state.abb)) %>% 
   bind_rows(tibble(state = "District of Columbia", abb = "DC"))

Then I joined it to my data:

left_join(data, st_crosswalk, by = "state")

Solution 5 - R

You can also use base::abbreviate if you don't have US state names. This won't give you equally sized abbreviations unless you increase minlength.

state.name %>% base::abbreviate(minlength = 1)

Solution 6 - R

If matching state names to abbreviations or the other way around is something you have to frequently, you could put Aniko's solution in a function in a .Rprofile or a package:

state_to_st <- function(x){
  c(state.abb, 'DC')[match(x, c(state.name, 'District of Columbia'))]
}


st_to_state <- function(x){
  c(state.name, 'District of Columbia')[match(x, c(state.abb, 'DC'))]
}

Using that function as a part of a dplyr chain:

enframe(state.name, value = 'state_name') %>% 
  mutate(state_abbr = state_to_st(state_name))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser227290View Question on Stackoverflow
Solution 1 - RAnikoView Answer on Stackoverflow
Solution 2 - RG. GrothendieckView Answer on Stackoverflow
Solution 3 - RXYZView Answer on Stackoverflow
Solution 4 - RBen GView Answer on Stackoverflow
Solution 5 - RpsychonomicsView Answer on Stackoverflow
Solution 6 - RsbhaView Answer on Stackoverflow