Нечеткое совпадение строк в R на числах, разделенных дефисами
Я пытаюсь сопоставить идентификаторы башни сотового телефона, содержащиеся в одной таблице, с основной таблицей местоположений (в лат.) Идентификаторов башни сотового телефона. Формат идентификаторов в таблице местоположений отличается от идентификаторов в первой таблице, и я пытаюсь использовать agrep()
сделать нечеткое совпадение. Чтобы дать вам пример, скажем, ID, который я пытаюсь сопоставить:
x <- c("405-800-125-39883")
Образец идентификаторов находится в таблице местоположений:
y <- c("405-810-1802-19883", "405-810-2101-29883", "405-810-1401-31883",
"405-810-5005-49883","125-39883","405-810-660-39883")
Я тогда использую agrep()
с разными комбинациями max.distance
:
agrep(x,y,max.distance=0.3,value=TRUE)
Это возвращает:
[1] "405-810-1802-19883" "405-810-2101-29883" "405-810-1401-31883" "405-810-5005-49883"
[5] "405-810-660-39883"
Принимая во внимание, что ценность, которую я действительно после "125-39883"
Я также попробовал stringdist_join()
функция от stringdist
пакет и применяется к двум фреймам данных bby по-разному max_dist
но безуспешно По сути, я ищу идеальное совпадение после последнего дефиса, а затем указание числа на втором последнем дефисе и так далее. Есть ли способ сделать это?
1 ответ
Вы можете векторизовать agrep
чтобы иметь возможность использовать все значения у в качестве шаблона. Ваша цель состоит в том, чтобы искать все y как часть x. Таким образом, ваш шаблон должен быть у, а не х
names(unlist(Vectorize(agrep)(y,x)))
[1] "125-39883"
Хотя мы можем использовать adist
с аргументом partial=TRUE
так что он может делать именно то, что agrep
делает:
y[which.min(c(adist(y,x,partial = T)))]
[1] "125-39883"
Если x
это вектор и y
также вектор, вы бы предпочли использовать adist
вместо agrep
, Все аргументы agrep
содержатся в adist
, Проверьте ?adist
для дальнейших деталей.
с вашим новым вопросом в комментариях вы можете сделать что-то вроде этого:
w=adist(y,x,partial=T)
z=setNames(nchar(sub(".*?(M*)$","\\1",c(attr(adist(y,x,counts=T),"trafos")))),y)
names(which.max(z[which(min(w)==w)]))
[1] "126-39883"