在 R 中标准化城市名称

问题描述

我是 R 和编码领域的新手,请原谅我在这里拼错了一些或更多的术语 (cmiiw)。

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

enter image description here

尝试使用 GetCloseMatchesstrdist_inner_join(我相信是模糊模糊)和 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

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

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

enter image description here

左>右

卡拉旺 - 到卡拉旺

雅加达北方飞往雅加达

雅加达到雅加达等

你知道最有效的方法吗?

非常感谢您的帮助!

问候

解决方法

您可以使用 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","Bintaro Tangerang Selatan","Emily","Tendean Jakarta Selatan 11750"
)


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

,

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

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

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

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

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

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

,

您可以使用 case_when 中的 dplyr 根据您的要求映射您的城市

library(dplyr) # for mutate and case_when

# demo data
data_input <- data.frame(num = c(1,2,3,4,5),city = c("Jakarta Barat","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)
         )
,

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

System.Text.Json.Serialization

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

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

上述解决方案还要求数据框中的城市名称拼写正确。如果您有拼写错误,例如雅加达而不是雅加达,那么需要一个更复杂的解决方案。

(经过编辑以包括提及一长串已知城市名称的能力)