r stringdist или levenshtein.distance для замены строк

У меня есть большой набор данных с ~ одним миллионом наблюдений, с ключом определенного типа наблюдения. В наборе данных имеется около 900 000 наблюдений с искаженными типами наблюдений, с примерно 850 (неправильными) вариациями 50 допустимых типов наблюдений.

keys <- c("DAY", "EVENING","SUNSET", "DUSK","NIGHT", "MIDNIGHT", "TWILIGHT", "DAWN","SUNRISE", "MORNING")

entries <- c("Day", "day", "SUNSET/DUSK", "DAYS", "dayy", "EVEN", "Evening", "early dusk", "late day", "nite", "red dawn", "Evening Sunset", "mid-night", "midnight", "midnite","DAY", "EVENING","SUNSET", "DUSK","NIGHT", "MIDNIGHT", "TWILIGHT", "DAWN","SUNRISE", "MORNING")

Использование gsub сродни рытью подвала ручной лопатой, а в моем случае — лопатой со сломанной ручкой, так как я новичок в r и сложных регулярных выражениях. Простой запасной вариант (для меня) состоит в том, чтобы написать по одному оператору gsub для каждого из принятых типов наблюдений, но это кажется излишне трудоемким, поскольку для этого требуется 50 операторов.

Я хотел бы использовать levenshtein.distance или stringdist, чтобы заменить ошибочные записи строкой кратчайшего расстояния. Запуск z <- for (i in length(y)) { z[i] = levenshtein.distance(y[i], x)} не работает, так как он пытается передать результаты (length(x)) каждому y[i].

Как вернуть результат с минимальным расстоянием? Я видел function(x) x[2], который возвращает второй результат в серии, но как получить самый низкий результат?


person Andrew M    schedule 22.10.2015    source источник
comment
Вы можете посмотреть документацию adist().   -  person RHertel    schedule 22.10.2015
comment
Вам нужно указать, какое совпадение вы считаете правильным при сравнении ЗАКАТА и ЗАКАТА с ЗАКАТОМ/ЗАКАТОМ,   -  person IRTFM    schedule 22.10.2015
comment
ЗАКАТ/СУМЕРКИ должны оцениваться как ЗАКАТ с помощью метода расстояния. Природа набора данных не позволяет мне определить, что больше подходит: ЗАКАТ или ЗАКАТ. ,   -  person Andrew M    schedule 22.10.2015


Ответы (1)


Вы можете попробовать:

library(stringdist)
m <- stringdistmatrix(entries, keys, method = "lv")
a <- keys[apply(m, 1, which.min)]

Если вы хотите поэкспериментировать с другим алгоритмом, взгляните на ?'stringdist-metrics'


Или, как указано @RHertel в комментариях:

b <- keys[apply(adist(entries, keys), 1, which.min)]

Из документации adist():

Вычислите приблизительное строковое расстояние между символьными векторами. Расстояние представляет собой обобщенное расстояние Левенштейна (редактирования), дающее минимально возможное взвешенное количество вставок, удалений и замен, необходимых для преобразования одной строки в другую.

Оба метода дают одинаковые результаты:

> identical(a, b)
#[1] TRUE
person Steven Beaupré    schedule 22.10.2015
comment
Я громко зааплодировала и напугала собаку! Большое спасибо вам обоим! Adist был именно тем, что я искал! ОГРОМНЫЕ УЛЫБКИ. Спасибо. - person Andrew M; 22.10.2015
comment
Красивое и элегантное решение! Спасибо. - person nd091680; 19.12.2019