标准化 R 中的城市名称
Standardize the City Name in R
我是 R 和编码世界的新手,请原谅我在这里可能拼错了一些或更多行话 (cmiiw)。
我面临着清理数据框中城市名称的挑战。
尝试使用 GetCloseMatches
、strdist_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)
)
您可以使用 map
和 str_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,则需要更复杂的解决方案。
(经过编辑以包含提及能力,以获得一长串已知城市名称)
我是 R 和编码世界的新手,请原谅我在这里可能拼错了一些或更多行话 (cmiiw)。
我面临着清理数据框中城市名称的挑战。
尝试使用 GetCloseMatches
、strdist_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)
)
您可以使用 map
和 str_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,则需要更复杂的解决方案。
(经过编辑以包含提及能力,以获得一长串已知城市名称)