Поиск строк, которые отличаются не более чем одной буквой от заданной строки в SAS с помощью PROC SQL - PullRequest
13 голосов
/ 26 апреля 2011

Сначала немного контекста. Я использую proc sql в SAS, и мне нужно извлечь все записи в наборе данных (с парой миллионов записей), у которых переменная «Name» равна (скажем, «Massachusetts»). Конечно, поскольку люди когда-то вводили данные вручную, возникают почти все возможные орфографические ошибки («Amssachusetts», «Kassachusetts» и т. Д.).

Я обнаружил, что немногие записи неправильно вводят более двух символов, поэтому код

Name like "__ssachusetts" OR Name like "_a_sachusetts" OR ... OR Name like "Massachuset__"

выберет записи, которые я ищу. Тем не менее, я надеюсь, что должен быть более удобный способ написать

Name that differs by at most 2 characters from "Massachusetts";

Есть? Или есть какая-то другая стратегия для получения этих записей? Я попытался выполнить поиск и в стеке, и в Интернете, но безуспешно. Я также относительный новичок в SQL и SAS.

Некоторая дополнительная информация: база данных не на английском языке (и фактическая строка не «Массачусетс»), поэтому использование SOUNDEX не реально (если это когда-либо было).

Заранее спасибо.

(Редактировать: улучшен заголовок)

Ответы [ 5 ]

13 голосов
/ 26 апреля 2011

SAS имеет встроенные функции COMPGED и COMPLEV для вычисления расстояний между строками.Вот пример, который показывает, как выбрать только те, у которых расстояние редактирования Левенштейна меньше или равно 2.

data typo;
input name $20.;
datalines;
massachusetts
masachusets
mssachusetts
nassachusets
nassachussets
massachusett
;

proc sql;
  select name from typo
  where complev(name, "massachusetts") <= 2;
quit;
4 голосов
/ 26 апреля 2011

Существуют другие фонетические алгоритмы, такие как Расстояние Хэмминга , которые должны работать лучше. Вы можете найти в Google для реализации этого алгоритма для вашей конкретной машины БД.

3 голосов
/ 26 апреля 2011

То, что вы ищете, это " Приблизительное совпадение строк ". Для этого можно использовать « алгоритм вычисления расстояния Левенштейна ». Я не уверен, но надеюсь, что этот ответ поможет

1 голос
/ 26 апреля 2011

Вы можете реализовать хранимую функцию этого типа (синтаксис Oracle, преобразовать в вашу СУБД):

CREATE FUNCTION distance(one VARCHAR2, two VARCHAR2) RETURN NUMBER IS
DETERMINISTIC
BEGIN
  -- do some comparison here
END distance;

А затем использовать его в SQL:

SELECT * FROM table WHERE distance(name, 'Massachusetts') <= 2

Конечно, эти вещи, как правило, довольно медленные ...

0 голосов
/ 02 сентября 2015

Я знаю, что это на четыре года позже, но так как это может также дать идеи другим, кто ищет эту тему: то, что вы рассматриваете, это семантический многоуровневый дизайн, вам нужно будет реализовать некоторую условную логику для этих различных сравнений текста,используя расстояния Lenvenschtien, такие как Jaro-Winkler, для сравнения текста разной длины и Хэмминга для текста той же длины, для которого вы предполагаете простое перемещение текста.Это не является чем-то новым в наши дни со всеми различными программами интеллектуального анализа текста.Вот пост, который на мой взгляд очень хорош; Функция сравнения строк Яро-Винклера в SAS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...