У меня большой набор данных с названиями городов.Многие из имен не согласованы.
Пример:
vec = c("New York", "New York City", "new York CIty", "NY", "Berlin", "BERLIn", "BERLIN", "London", "LONDEN", "Lond", "LONDON")
Я хочу использовать fuzzywuzzyR
, чтобы привести их в согласованный формат.Проблема в том, что у меня нет основного списка исходных названий городов.
Этот пакет предоставляет возможность обнаруживать дубликаты следующим образом:
library(fuzzywuzzyR)
init_proc = FuzzUtils$new()
PROC = init_proc$Full_process
init_scor = FuzzMatcher$new()
SCOR = init_scor$WRATIO
init = FuzzExtract$new()
init$Dedupe(contains_dupes = vec, threshold = 70L, scorer = SCOR)
dict_keys(['New York City', 'NY', 'BERLIN', 'LONDEN'])
Или я могу установить «мастер-значение», например:
master = "London"
init$Extract(string = master, sequence_strings = vec, processor = PROC, scorer = SCOR)
[[1]]
[[1]][[1]]
[1] "London"
[[1]][[2]]
[1] 100
[[2]]
[[2]][[1]]
[1] "LONDON"
[[2]][[2]]
[1] 100
[[3]]
[[3]][[1]]
[1] "Lond"
[[3]][[2]]
[1] 90
[[4]]
[[4]][[1]]
[1] "LONDEN"
[[4]][[2]]
[1] 83
[[5]]
[[5]][[1]]
[1] "NY"
[[5]][[2]]
[1] 45
Мой вопросКак я могу использовать это, чтобы заменить все совпадения в списке с тем же значением, то есть я хотел бы заменить все значения, которые соответствуют основному значению, с "Лондон".Тем не менее, у меня нет основных ценностей.Итак, мне нужно иметь список совпадений и заменить значения.В этом случае это будет «Нью-Йорк», «Лондон», «Берлин».После процесса vec
должен выглядеть следующим образом.
new_vec = c("New York", "New York", "New York", "New York", "Berlin", "Berlin", "Berlin", "London", "London", "London", "London")
Обновление
@ Камилла пришла в голову идея использовать world.cities
из maps
пакет.Я нашел эту запись с использованием fuzzyjoin
, имеющую дело с аналогичной проблемой.
Чтобы использовать это, я конвертирую vec
во фрейм данных.
vec = as.data.frame(vec, stringsAsFactors = F)
colnames(vec) = c("City")
Затем с помощьюпакет fuzzyjoin
вместе с world.cities
пакета maps
.
library(maps)
library(fuzzyjoin)
vec %>%
stringdist_left_join(world.cities, by = c(City = "name"), distance_col = "d") %>%
group_by(City) %>%
top_n(1)
Вывод выглядит так:
# A tibble: 50 x 3
# Groups: City [5]
City name d
<chr> <chr> <dbl>
1 New York New York 0
2 NY Ae 2
3 NY Al 2
4 NY As 2
5 NY As 2
6 NY As 2
7 NY Au 2
8 NY Ba 2
9 NY Bo 2
10 NY Bo 2
# ... with 40 more rows
Проблема в том, что я понятия не имею, какиспользовать расстояние между ´name and
City`, чтобы изменить значения с ошибками на правильные для всех городов.В теории корретное значение должно быть наиболее близким.Но то есть для Нью-Йорка это не так.