Join Now

Juletip? COMPGED() og COMPLEV() funktionerne

by SAS Employee LarsL_Andersson on ‎12-07-2014 09:16 AM (235 Views)

27. april 2012 postede jeg om dette emne på "SAS Forum DK" LinkedIn-gruppen, men mon ikke det er relevant at gentage her på SAS Community Denmark?!

Funktionerne COMGED() og COMPLEV() er begge en del af Base SAS. De kan ikke betegnes "nye", men jeg har indtryk af at kendskab til disse funktioner blandt SAS-brugere ikke er specielt udbredt.

Begge funktioner tager to tekst-strenge som input-argumenter, og returnerer et tal. Tallet repræsenterer "afstanden" mellem de to strenge, sådan at to identiske tekststrenge har en afstand på 0. COMPGED() og COMPLEV() beregner afstanden efter to forskellige algoritmer. Detaljer omkring dette kan læses i dokumentationen (http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002206133.htm og http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002206137.htm)

Men hvad kan det bruges til? Jeg har anvendt det i sammenhæng med SAS' datakvalitets-funktioner, hvor de er et fint supplement. Mens datakvalitets-funktioner som DQMATCH() overvejende evaluerer fonetisk lighed mellem de sammenlignede tekststrenge, så er edit distances velegnede til at fange små tastefejl som fundamentalt ændrer "lyden" af et bestemt navn, sådan at matchkoder ikke bliver identiske selv med en lav sensitivity level (f.eks. "Lars L. Andersson" fejlagtigt indtastet som "Lars L. Anedrsson").

Hvis man f.eks. har en lang liste med tekststrenge (personnavne, vejnavne, bynavne eller en kombination heraf) og man gerne vil have en liste over samtlige par med en edit distance under en bestemt værdi, så kan man bare bruge COMPGED eller COMPLEV funktionen i en SQL á la dette:

data work.mineTekstStrenge;

   minTekstStreng = 'Jens Jensen    '; output; 

   minTekstStreng = 'Jesn Jensen    '; output;

   minTekstStreng = 'Jens Petersen  '; output;

   minTekstStreng = 'Peter Petersen '; output;

run;

%let taerskel=2;

proc sql;

   create table work.maaske_identiske_par as

      select a.minTekstStreng as minTekstStreng1

            ,b.minTekstStreng as minTekstStreng2

      from work.mineTekstStrenge as a

          ,work.mineTekstStrenge as b

      where (a.minTekstStreng lt b.minTekstStreng)

        and (complev(a.minTekstStreng, b.minTekstStreng, %eval(&taerskel.+1), 'ILN') le &taerskel.)

;

quit;

Bemærk at SAS melder: "The execution of this query involves performing one or more Cartesian product joins (...)" - så for større mængder data vil det være smart om muligt at udvide join-kriterierne i SQL'en sådan, at mængden af evaluerede par reduceres mest muligt - f.eks. ved ikke at sammenligne personnavne i hver deres postnummer...