标准化 R 中的城市名称

Standardize the City Name in R

我是 R 和编码世界的新手,请原谅我在这里可能拼错了一些或更多行话 (cmiiw)。

我面临着清理数据框中城市名称的挑战。

尝试使用 GetCloseMatchesstrdist_inner_join(我相信是 fuzzywuzzy)和 dplyr 风格,但仍然不能满足我的需求。

第一次尝试:

vec3 = unlist(world.cities$name)

str1 = c('Jakarta Utara')

GetCloseMatches(string = str1, sequence_strings = vec3, n = 1L, cutoff = 0.6)

但它每次只能“翻译”一个城市,你知道如何让它对所有数据帧重复吗? for 循环还是函数?

第二次尝试:

df2 <- df[1:10,] %>%

stringdist_left_join(world.cities, by = c(cust_city = "name"), max_dist = 1)

它显示了大部分城市,但缺少“Jakarta Utara”

我正在使用两个 database/dataframe(cmiiw) 的城市进行检查(如果您看到右侧的“查找”table,它有数百个城市名称,不仅 6),第一个是我强化的 SHP 文件,第二个是 world.cities$name,两者都做得很好,但不知何故它一次只出现一个城市。即:如果我使用 SHP 文件,Jakarta Utara 会出现但 Karawang 不会出现,反之亦然。

我的目标是将左边的单词替换为右边的单词(1 到 2)

左 > 右

卡拉旺-到卡拉旺

雅加达北到雅加达

雅加达到雅加达等

你知道最有效的方法吗?

非常感谢您的帮助!

问候

我已经更新了答案以使用与 maps::world.cities 的匹配来选择更多国家/地区。

library(tidyverse)
library(maps)
library(fuzzyjoin)

wc <- world.cities %>% 
  as_tibble()

table <- data.frame(
  customers = seq(1, 5, 1),
  city = c(
    "Jakarta Barat",
    "Jakarta",
    "Nagoya Batam",
    "Bintaro Tangerang Selatan",
    "Tendean Jakarta Selatan 11750"
  )) %>% 
  as_tibble() %>% 
  mutate(country = "Indonesia")

table %>% 
  regex_inner_join(wc, 
                   by = c(city = "name",
                          country = "country.etc"))

我已将国家/地区列添加到我的数据中以使联接更加准确。这可以扩展到数百个城市。

您可以使用 dplyr 中的 case_when 根据您的要求绘制城市地图

library(dplyr) # for mutate and case_when

# demo data
data_input <- data.frame(num = c(1,2,3,4,5), 
                         city = c("Jakarta Barat", "Jakarta", "Nagoya Batam", 
                                  "Bintaro Tangerang Seltan", "Tandean Jakarta Selatan"), 
                         stringsAsFactors = FALSE)

# Use case_when to mapp according to mapping table
output_reqd <- data_input %>% 
  mutate(new_city = case_when(grepl(pattern = "Jakarta", x = city) ~ "Jakarta",
                              grepl(pattern = "Batam", x = city) ~ "Batam",
                              grepl(pattern = "Tangerang Seltan", x = city) ~ "Tangerang Seltan",
                              TRUE ~ city)
         )

您可以使用 mapstr_detect。如果有效请告诉我。

library(tidyverse)

df %>%
  mutate(City = map(City, ~df1$City[str_detect(.x,df1$City)])) %>% 
  unnest ()

输出:

# A tibble: 5 x 3
  Name      Qty City             
  <chr>   <dbl> <chr>            
1 Alex       10 Jakarta          
2 Bambang     5 Jakarta          
3 Charlie    15 Batam            
4 Delta      10 Tangerang Selatan
5 Emily       5 Jakarta   

数据:

df <- tribble(
~Name, ~Qty, ~City,
"Alex", 10, "Jakarta Barat",
"Bambang", 5, "Jakarta",
"Charlie", 15, "Nagoya Batam",
"Delta", 10, "Bintaro Tangerang Selatan",
"Emily", 5, "Tendean Jakarta Selatan 11750"
)


df1 <- tribble(
~City,
"Jakarta",
"Bandung",
"Batam",
"Surabay",
"Tangerang Selatan"
)

如果我理解你的问题,你想根据已知城市名称列表解析 City 变量,并将较长的城市名称替换为已知城市名称列表中的版本。正确的?如果是,那么希望这种方法对你有用(不需要额外的包):

# replicate your example data 1
d <-data.frame("No"=c(1,2,3,4,5),"Name"=c("Alex","Bambang","Charlie","Delta","Emily"),"Qty"=c(10,5,15,10,5),"City"=c("Jakarta Barat","Jakarta","Nagoya Batam","Bintaro Tangerang Selatan","Tendean Jakarta Selatan 11750"))
# replicate your vector of known city names
city_list <- c("Jakarta","Bandung","Batam","Surabaya","Tangerang Selatan")

# making a new placeholder variable to store the matched city names.
d$City_fix <- NA

# use a for loop, ifelse(), and grepl() to go through the vector of known cities, and replace the city name when a match is found.
for (i in 1:length(city_list)){
  d$City_fix <- ifelse(grepl(city_list[i], d$City), city_list[i], d$City_fix)
}

# view results
d

  No    Name Qty                          City          City_fix
1  1    Alex  10                 Jakarta Barat           Jakarta
2  2 Bambang   5                       Jakarta           Jakarta
3  3 Charlie  15                  Nagoya Batam             Batam
4  4   Delta  10     Bintaro Tangerang Selatan Tangerang Selatan
5  5   Emily   5 Tendean Jakarta Selatan 11750           Jakarta

使用已知城市的向量将允许您在循环中访问任意数量的城市。如果您有两个城市可能共享同一个城市名称的部分内容,请当心,例如“大城市”和“新大城市”。

如果源数据框中的城市名称或城市列表中的大小写不同,您需要先修复它(例如 tolower()from base R 或 str_to_title()来自 stringr 包)。

上述解决方案还要求数据框中的城市名称拼写正确。如果您有拼写错误,例如Jakerta 而不是 Jakarta,则需要更复杂的解决方案。

(经过编辑以包含提及能力,以获得一长串已知城市名称)