2011-04-26 34 views
13

Primero algo de contexto. Estoy usando proc sql en SAS, y necesito buscar todas las entradas en un conjunto de datos (con un par de millones de entradas) que tienen la variable "Nombre" igual a (digamos) "Massachusetts". Por supuesto, dado que los datos fueron ingresados ​​manualmente por humanos, se producen cerca de todos los errores ortográficos concebibles ("Amssachusetts", "Kassachusetts", etc.).Encontrar cadenas que difieran, como máximo, de una letra de una cadena determinada en SAS con PROC SQL

He encontrado que algunas entradas reciben más de dos caracteres mal, por lo que el código de

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

gustaría seleccionar las entradas Estoy buscando. Sin embargo, espero que haya una manera más conveniente de escribir

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

¿Hay alguna? ¿O hay alguna otra estrategia para obtener estas entradas? Intenté buscar stackoverflow y la web, pero no tuve éxito. También soy un principiante relativo tanto con SQL como con SAS.

Alguna información adicional: La base de datos no está en inglés (y la cadena real no es "Massachusetts") por lo que usar SOUNDEX no es realmente factible (si alguna vez lo fue).

Gracias de antemano.

(Edit: Mejorado el título)

+0

¿cuál es su motor de base de datos? p.ej. base SAS, DB2, etc. – trickwallett

+0

@trickwallett: Solo base SAS. – Har

Respuesta

13

SAS tiene funciones integradas COMPGED y COMPLEV para calcular distancias entre cadenas. He aquí un ejemplo que muestra cómo seleccionar sólo a aquellos con una distancia de edición Levenshtein inferior o igual a 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; 
+0

Maravilloso. Esto parece ser perfecto. Lo verificaré por primera vez en la mañana (y luego haré clic en la marca de verificación :)). – Har

4

Hay otros algoritmos fonéticos como Hamming distance que deberían funcionar mejor. Puede buscar en Google la implementación de este algoritmo para su motor de DB específico.

+0

Gracias. No sabía que se llamaba la distancia de Hamming. – Har

+0

+1 para otra solución.Tenía curiosidad sobre la diferencia entre Hamming Distance y [Levenshtein distance] (https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance) que se cita en la respuesta aceptada. Básicamente, no creo que Hamming Distance sea "mejor", como implica esta respuesta, porque Levenshtein solo trata una transposición como un costo de 1, no de 2. Entonces, en la situación de OP, si la entrada tenía dos conjuntos de transposición cartas tendría un puntaje de Levenshtein de 2, pero un puntaje de Hamming de 4. Solo consideraría una transposición como un solo error, por lo que creo que Levenshtein es más preciso. –

1

podría implementar una función almacenada de este tipo (la sintaxis de Oracle, transformar a su RDBMS):

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

y luego usarlo en SQL:

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

Por supuesto, estas cosas tienden para ser bastante lento ...

+0

De acuerdo. Que es lento está bien (después de todo, ya lo estoy haciendo y el tiempo no es un problema, especialmente en comparación con el tiempo de programación). Tendré que analizar más a fondo la posibilidad de definir funciones de SQL de SAS. Gracias. – Har

0

Sé que esto es de cuatro años demasiado tarde, pero ya que también podría dar ideas a otros que están buscando este hilo: Lo que está considerando es un diseño de capas semánticas que necesitaría implementar alguna lógica condicional para estas diferentes comparaciones de texto, utilizando distancias Lenvenschtien como Jaro-Winkler para comparar textos de diferentes longitudes y Hamming para los de la misma longitud para la cual se supone transposicionamiento de texto simple. Esto no es nada nuevo en estos días con todos los diversos programas de minería de textos que hay. Aquí hay una publicación que es muy buena desde mi punto de vista; Jaro-Winkler string comparison function in SAS

Cuestiones relacionadas