Replace multiple values using a reference table

百般思念 提交于 2021-02-19 07:34:09

问题


I’m cleaning a data base, one of the fields is “country” however the country names in my data base do not match the output I need.

I though of using str_replace function but I have over 50 countries that need to be fix, so it’s not the most efficient way. I already prepared a CSV file with the original country input and the output I need for reference.

Here is what I have so far:

library(stringr)
library(dplyr)
library(tidyr)
library(readxl)
database1<- read_excel("database.xlsx") 
database1$country<str_replace(database1$country,"USA","United States")
database1$country<str_replace(database1$country,"UK","United Kingdom")
database1$country<str_replace(database1$country,"Bolivia","Bolivia,Plurinational State of")
write.csv(database1, "test.csv", row.names=FALSE, fileEncoding = 'UTF 8', na="")

回答1:


Note: levels and labels inside the factor must be unique or it should not contain duplicates.

# database1 <- read_excel("database.xlsx")  ## read database excel book
old_names <- c("USA", "UGA", "CHL") ## country abbreviations
new_names <- c("United States", "Uganda", "Chile")  ## country full form

base R

database1 <- within( database1, country <- factor( country, levels = old_names, labels = new_names ))

Data.Table

library('data.table')
setDT(database1)
database1[, country := factor(country, levels = old_names, labels = new_names)]

database1
#          country
# 1: United States
# 2:        Uganda
# 3:         Chile
# 4: United States
# 5:        Uganda
# 6:         Chile
# 7: United States
# 8:        Uganda
# 9:         Chile

Data

database1 <- data.frame(country = c("USA", "UGA", "CHL", "USA", "UGA", "CHL", "USA", "UGA", "CHL"))
#    country
# 1     USA
# 2     UGA
# 3     CHL
# 4     USA
# 5     UGA
# 6     CHL
# 7     USA
# 8     UGA
# 9     CHL

EDIT: You can create one named vector countries, instead of two variables such as old_names and new_names.

countries <- c("USA", "UGA", "CHL")
names(countries) <- c("United States", "Uganda", "Chile")
within( database1, country <- factor( country, levels = countries, labels = names(countries) ))



回答2:


Have wrangled problems like this in the past using a similar method using a .csv file to do bulk replacements.

Example .csv file format:

library(data.table)

## Generate example replacements csv file to see the format used
Replacements <- data.table(Old = c("USA","UGA","CHL"),
                           New = c("United States", "Uganda", "Chile"))

fwrite(Replacements,"Replacements.csv")

Once you have your "Replacements.csv", you can use that to replace all the names at once using stringi::replace_all_regex(). (For what it's worth, pretty much the entire stringr package is essentially a wrapper around calls to stringi. Since stringi runs slightly faster and has a larger set of functionalities, I prefer to stick with stringi.) See stringi vs stringr blog by HRBRMSTR

library(data.table)
library(readxl)
library(stringi)

## Read in list of replacements
Replacements <- fread("Replacements.csv")

## Read in file to be cleaned
database1<- read_excel("database.xlsx")

## Perform Replacements
database1$countries <- stringi::stri_replace_all_regex(database1$countries,
                                              "^"%s+%Replacements$Old%s+%"$",
                                              Replacements$New,
                                              vectorize_all = FALSE)

## Write CSV
write.csv(database1, "test.csv", row.names=FALSE, fileEncoding = 'UTF 8', na="")

I tried to use base R data.frame syntax above where possible to avoid any confusion, but if I were doing this for my self I'd stick to the full data.table syntax as follows:

library(data.table)
library(readxl)
library(stringi)

## Read in list of replacements
Replacements <- fread("Replacements.csv")

## Read in file to be cleaned
database1<- read_excel("database.xlsx")

## Perform Replacements
database1[, countries := stri_replace_all_regex(countries,"^"%s+%Replacements[,Old]%s+%"$",
                                              Replacements[,New],
                                              vectorize_all = FALSE)]
## Write CSV
fwrite(database1,"test.csv")


来源:https://stackoverflow.com/questions/48002479/replace-multiple-values-using-a-reference-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!