Macro de SAS que he utilizado hoy para limpiar caracteres en una cadena de texto. Está muy limitada y es muy sencilla pero puede serviros:


%macro valida(in,out);
length escribe $55.;
escribe="";
do i=1 to length(&in.);
  j=substr(&in.,i,1);
 if j in ('A','B','C','D','E','F','G','H','I','J','K',
 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Ñ') then escribe=trim(escribe)||j;
 else if substr(&in.,i,1)=" " then escribe=trim(escribe)||"-";
 else escribe=trim(escribe);
 drop i j escribe;
end;
&out.=tranwrd(compress(escribe),"-"," ");
%mend;

Es bastante mala y limitada, insisto. Si alguien aporta algo se agradecerá. El tema es que recorre una variable alfanumérica carácter a carácter y si no es una letra mayúscula se lo chimpunea sin ningún miramiento, aporta un poco más de talento cuando aparece un espacio en blanco. Ahí va el ejemplo de uso:


data _null_;
y="ME.N9UDA@ CAGA--;DA vENIR";
%valida(upcase(y),x);
put x=;
run;

En fin, si la voy mejorando lo sigo comunicando. Por cierto, esto se puede hacer con WPS a la perfección. Si alguno de vosotros está interesado en WPS o tiene ya jornada de verano y necesitan consultoría que me escriba a rvaquerizo@analisisydecision.es

18 pensiamientos en “Macros SAS. Limpiar una cadena de caracteres

  • Dani Fernandez

    Raul, no estaría de más quitarte esta ‘carga’ de encima y dejarsela al dromedario (por aquello del Libro del Dromedario, este es ‘Programming Perl’), que bien podría significar ‘Practical Extraction and Report Language’ traducido al español como ‘Lenguaje Práctico para la Extracción e Informe’ creado por un lingüista,
    Larry Wall:
    http://www.linuxjournal.com/article/3394

    Como SAS admite ReGex (Perl REgular Expressions),
    aquí vamos:

    data test;
    y=”ME.N9UDA@ CAGA–;DA vENIR”;
    x=upcase(y);
    call prxchange(prxparse(‘s/([A-Za-z]*)([^A-Za-z ]*)/$1/’),-1,x);
    put y= / x=;
    run;

    Output:

    y=ME.N9UDA@ CAGA–;DA vENIR
    x=MENUDA CAGADA VENIR

    Por cierto, eso de ‘chimpunea’´… hasta mí me cuesta enterderlo, ya no sé qué entenderan
    los del otro lado del charco. Me encomiendo la tarea de traducirlo para ellos como ‘se lo pasa de largo, omite todo lo que no sean letras o espacios’, jaja!

    un saludo!!
    Dani Fernández.

    Responder
  • Dani Fernandez

    Veo que el copypaste de mi código no percibe correctamente las comillas.
    el código correcto sería (a de llevar comillas o doble comillas, en vez de acentos):

    data test33;
    y=’ME.N9UDA@ CAGA–;DA vENIR’;
    x=upcase(y);
    call prxchange(prxparse(‘s/([A-Za-z]*)([^A-Za-z ]*)/$1/’),-1,x);
    put y= / x=;
    run;

    Responder
  • rvaquerizo

    Dani, estas funciones de Perl, que nunca me he atrevido a utilizar, ¿funcionan en todos los sistemas operativos? No veo haciendo esto en un Mainframe. Ojo porque tienen el problema de la Ñ.

    Por cierto, he hecho pruebas de rendimiento. Esta rutina gasta el doble de memoria y tarda la mitad menos.

    Tenía preparada una macro que hacía maravillas que iba a ir en sucesivas entregas. Ahora voy a tener que emplear esta rutina. Interesante

    Responder
  • Dani Fernandez

    A partir de la version 9.0 SAS introdujo funciones ‘pattern matching’ (busqueda de patrones de texto) llamadas PRX (Perl Regular Expressions), así que realmente funcionarán si SAS funciona (así de simple, siempre y cuando la versión sea superior a 9.0).

    Teniendo en cuenta lo que me decías de la ‘Ñ’, buena observación!, he testeado este otro código y funciona correctamente (hemos de añadir la Ñ explícita porque cuando declaramos el abecedario desde la A-Z, este no recoge la Ñ;
    por qué será… ?? .. Con “Sheispir” hemos topado!!

    data prueba_enye; * la Ñ de España;
    y=’5eL A5ÑO Q$%ue vi4en=E’;
    x=upcase(y);
    call prxchange(prxparse(‘s/([A-ZÑa-zñ]*)([^A-Za-zÑñ ]*)/$1/’),-1,x);
    put y= / x=;
    run;

    y=5eL A5ÑO Q$%ue vi4en=E
    x=EL AÑO QUE VIENE

    Pues nada, estamos para ayudar!
    En breve presento algunas entregas en tu web.

    Daniel Fernández.

    Responder
  • ffernandez

    Yo las descubrí también hace poco, y desde entonces “Soy fan”. Las utilicé para identificar una estructura de operaciones matemáticas en una cadena de caracteres (Algo así como “cantidadAxCantidadb”). Iba a preparar una contestación al post pero se me ha adelantado Daniel ^_^. Saludos.

    Responder
  • Daniel Fernandez

    Yo llevo detras de ellas un año, pero ha sido en el trabajo cuando he tenido que recurrir forzosamente a ellas al tratar de cuantificar registros de nomenclaturas médicas (classificación médica ‘SNOMED’).
    Por ejemplo todas aquellas clasificaciones de morfologia médica que empieza en M….

    http://en.wikipedia.org/wiki/International_Classification_of_Diseases_for_Oncology).

    Las funciones PRX de SAS sirven muy bien para tratar texto, cuantificar, cambiar, alterar palabras, numeros, vocablos, etc etc…
    Se usa mucho para evaluar códigos postales americanos, los famosos ZIP o bien depurar números telefónicos, por ejemplo, si el teléfono fijo de un cliente empieza por 91 o (91) o 91. o bien -91-, etc etc sabremos que pertenece a Madrid. Repito, sirve muy para hace limpieza de datos (depuración o ‘datacleansing’).

    un saludo!
    Entre todos aprendemos unos de otros….
    Dani Fernández.

    Responder
  • rvaquerizo

    Al final acabamos creando algún proceso que identifique estructuras sintácticas. Me ha gustado el tema.

    Responder
  • mery

    Hola
    La función compress de SAS admite bastantes posibilidades si se parametriza correctamente podeis limpiar cualquier valor alfanumérico:

    data _null_;
    y1=”ME.N9UDA@ CAGA–;DA vENIR”;
    y2=”5eL A5ÑO Q$%ue vi4en=E”;
    x1=compress(upcase(y1),’ABCDEFGHIJKLMNÑOPQRSTUVWXYZ ‘,’k’);
    x2=compress(upcase(y2),’ABCDEFGHIJKLMNÑOPQRSTUVWXYZ ‘,’k’);
    put x1=;
    put x2=;
    run;

    Un saludo!

    Responder
  • cgbellosta

    Hola…

    Efectivamente, como desde el 2004 están disponibles las expresiones regulares en SAS; e iba siendo hora porque son lo más útil que se ha inventado en siglos.

    El problema es que casi nadie sabe manejarlas. Pero se pueden hacer virguerías con ellas…

    ¿Has visto si están implementadas en WPS?

    Responder
  • rvaquerizo

    Hay que mirar si esto se puede hacer con WPS. De todos modos se puede sobrevivir casi 10 años sin conocerlas e incluso mirando estas expresiones con ligero recelo.

    Responder
  • Daniel Fernández

    jaja, Raul lo quiere hacer ahora todo con WPS!!
    WPS = World Perl Solution??

    Si me animo algún día escribiré sobre trucos
    RegEx en SAS, sobretodo allí donde SAS no puede llegar y por ello integró las regular expressions.

    Un saludo!

    Dani Fernández.

    Responder
  • rvaquerizo

    Todo se puede hacer con WPS por mucho menos pasta. Ya me daréis la razón ya.

    Responder
  • Daniel Fernandez

    …yo diría más bien que eso que buscas ya lo tienes en tus manos : R !!
    No olvides que el paquete RSPerl te permite
    usar Perl desde R y viceversa:
    http://www.omegahat.org/RSPerl/

    un saludo,
    Dani Fernandez

    Responder
  • ffernandez

    Ya, pero me imagino que WPS tendrá más o menos solventado el problema de las tablas gigantes mejor que R… (ya sabemos que hay alternativas, pero hablo de no tener que recurrir a software adicional)

    Responder
  • rvaquerizo

    En WPS no funciona. Habría que emplear las macros cutre salchichas que tengo.

    Responder
  • Adriana

    Hola! Tengo una variable (var) que está de la siguiente manara var = Name=”Milk protein yield (EBV) QTL #14915″.
    Lo que quiero es generar una variable que sólo extraiga lo siguiente: Milk protein yield (EBV).
    Como le puedo hacer con RegExpr?
    Gracias

    Responder
  • rvaquerizo

    Hola Adriana, para eso emplea substr+index, no te compliques.

    Responder
  • Federico C

    Buenas tardes a todos es mi primer comentario. Soy un usuario relativamente nuevo de la herramienta SAS GUIDE. Estoy necesitando analizar campos de texto.
    Tengo el dato de domiclio de determinadas personas en mi BD y recibo de un proveedor el mismo dato pero con otro formato (calle, número, codpostal, etc todo junto).
    Más allá de la normalización de los datos lo que necesito es comparar texto donde me devuelva un resultado y con dicho resultado poder tomar una decisión donde se infiere que ambas direcciones coinciden en mayo o menor medida:

    EJ1: BD: Gral Artigas 2899 / Proveedor: Artigas 2899 – Resultado Prob 90%
    EJ2: BD: Gral Artigas 2899 / Proveedor: Gervasio Artigas Gral 2899 – Resultado Prob 70%
    BD: Gral Artigas 2899 / Proveedor: Gral Artigas 2899 – Resultado Prob 100%

    Espero se entienda la consulta y me puedan ayudar.

    Muchas gracias, Federico.

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *