Расстояние Левенштейна: устранение несоответствий в написании строковых переменных

#r #string #levenshtein-distance

#r #строка #расстояние Левенштейна

Вопрос:

Я новичок в работе со строками, и у меня есть головоломка. У меня очень большой набор данных, который выглядит примерно так:

 > df <- data.frame(id= c("abc name","abc names","abc name","other","very very long name","abc other id","bbc other id","other long name","two names"),x1 = rnorm(9), x2= rnorm(9))
> print(df)
#                   id          x1         x2              
# 1            abc name  0.38827655 -0.6855575
# 2           abc names -1.01248116 -0.4221539 
# 3            abc name  0.05076442 -0.7953287 
# 4               other -1.04510310 -0.4795451 
# 5 very very long name  1.27578095  0.3470104 
# 6        abc other id -0.22093223 -0.5508261 
# 7        bbc other id  0.47213061  0.4396293 
# 8     other long name  0.66464296 -0.2405145 
# 9           two names -0.17877376 -0.6957395 
  

Проблема с этими данными заключается в том, что переменная id содержит некоторые орфографические ошибки. Например, строки 1,2 и 3 сообщают данные для одного и того же идентификатора, однако они записаны с немного разными именами («abc name» против «abc names»).

Я хотел бы создать новый столбец (id_lev), который создает новые имена идентификаторов, устраняя орфографические ошибки. Это должно быть рассчитано с использованием расстояния Левенштейна (количество правок, необходимых для перехода от одного имени к другому, пропорционально длине имени).

Последний столбец должен соответствовать следующим правилам:

  1. рассмотрим два одинаковых имени, если их расстояние Левенштейна <= 0,5
  2. замените имена с менее распространенным написанием на более распространенное написание (например. строка 2 должна стать «именем abc», чтобы соответствовать строкам 1 и 3).
  3. если ни один из идентификаторов не является более популярным, следует предпочесть первый появившийся. Следовательно, в строках 6 и 7 должно стать «abc other id».

Конечный набор данных должен выглядеть примерно так: (конечно, результаты id_lev будут зависеть от того, является ли расстояние Левенштейна <= 0,5 правилом.)

 #                   id          x1         x2              id_lev
# 1            abc name  0.38827655 -0.6855575            abc name
# 2           abc names -1.01248116 -0.4221539            abc name
# 3            abc name  0.05076442 -0.7953287            abc name
# 4               other -1.04510310 -0.4795451               other
# 5 very very long name  1.27578095  0.3470104 very very long name
# 6        abc other id -0.22093223 -0.5508261        abc other id
# 7        bbc other id  0.47213061  0.4396293        abc other id
# 8     other long name  0.66464296 -0.2405145     other long name
# 9           two names -0.17877376 -0.6957395           two names
  

Заранее большое спасибо за вашу помощь

С наилучшими пожеланиями

Комментарии:

1. Почему существует расстояние 0,5? Вы имеете в виду, что затраты на редактирование различаются в зависимости от типа редактирования (например, вставка = 0,5, удаление = 0,5 и замена = 1)?

2. Извините, что не слишком ясно об этом. Я имею в виду, что расстояние должно быть разделено на длину строки (расстояние / длина должно быть <= 0,5), чтобы гарантировать, что для более длинных имен допускаются строки большего размера.