Trucos

Abreviar código en Enterprise Guide

En Enterprise Guide de SAS podemos ahorrarnos código empleando las abreviaturas del editor. Yo no lo recomiento porque nuestros códigos sólo podrán ser ejecutados con nuestros equipos pero Guide es una herramienta pensada para los usuarios y no para el desarrollo de código. Sobre un programa de Guide pulsamos sobre programas-> Añadir Abreviaturas y aparece la siguiente ventana:abreviatura_enterprise_guide.PNGEn la ilustración que os pongo hemos creado la abreviatura ps que equivale a proc sql. Con ello cada vez que en el editor de programas de Guide pongamos ps veremos lo siguiente:abreviatura_enterprise_guide-2.PNGEl editor entiene que estamos escribiendo proc sql y pulsando el TAB podemos ahorrarnos escribir mucho mucho código.

Trucos SAS. Ejecutar un código si existe una tabla o un fichero

Esta duda me llegó hace unos días. Se trataba de ejecutar un código si existía determinado fichero o determinada tabla. Para hacer esto os planteo una posible metodología que yo utilizaba cuando programaba SAS en una gran entidad bancaria con Enterprise Guide 1, por aquellos entonces hacía maravillas con la castaña del Guide v1. Entre ellas unas macros que contenían una sentencia condicional que ejecutaba un código en función de la función (bonita expresión) EXIST o FILEEXIST. Lo que yo hacía era algo parecido a esto:

Macros (fáciles) de SAS. Normaliza un texto rápido

¿Tienes que normalizar un texto con SAS? Llevas 2 horas buscando funciones de texto con la ayuda y te has crispado. En una macro y de forma muy rápida os planteo un muestrario de funciones con las que podéis normalizar (un poco) un texto. Esto es algo que tuve que hacer la otra mañana no es muy sofisticado pero que puede seros de utilidad:

%macro prepara(varib);

&varib.=translate(&varib.,"AEIOU","ÁÉÍÓÚ");

&varib.=tranwrd(&varib.,"NUM","NUMERO");

&varib.=tranwrd(&varib.,"CONT","CONTABLE");

&varib.=tranwrd(&varib.,"IMP ","IMPORTE ");

&varib.=tranwrd(&varib.," POR "," ");

&varib.=tranwrd(&varib.," DE "," ");

&varib.=tranwrd(&varib.," EN "," ");

&varib.=tranwrd(&varib.," LOS "," ");

&varib.=tranwrd(&varib.," AL "," ");

&varib.=tranwrd(&varib.," EL "," ");

&varib.=tranwrd(&varib.," ULTIMOS 12 "," 12 ");

&varib.=tranwrd(&varib.," ULTIMOS 3 "," 3 ");

&varib.=tranwrd(&varib.," ULTIMO MES "," MES ");

&varib.=tranwrd(&varib.," TRANSACCIOENES "," TRANSACCIONES ");

call prxchange(prxparse('s/([A-ZÑa-zñ 0-9]*)([^A-Za-zÑñ 0-9]*)/$1/'),-1,&varib.);

%mend;

En realidad es una sucesión de TRANWRD pero destacaría el uso de la función TRANSLATE para eliminar tildes en nuestras vocales y el uso de CALL PRXCHANGE del que ya tuvimos un aperitivo hace tiempo. Sólo tenéis que copiar y pegar y si tenéis dudas mejor seguid el hilo porque últimamente me están llegando demasiadas por correo y no dispongo de tiempo, algo que ya habréis detectado muchos de los seguidores del blog. De todos modos tengo trucos de estos para seguir dotando de contenido al blog en los próximos meses. Por cierto, si alguien lo mejora que siga el hilo…

Trucos Excel. Archivos de un directorio con una macro

Puede resultarnos útil tener todos los archivos de un directorio en una tabla de excel. Si estamos documentando un proceso, si nos dan un gran número de ficheros y tenemos que realizar procesos repetitivos sobre ellos, si queremos tener inventariados nuestros programas,… Para esto os planteo una macro bien sencilla que recorre un directorio y nos escribe los elementos que encuentra en él. El código visual basic para la macro en Excel no puede ser más sencillo:

Duda de SAS. Longitud de la parte decimal de un número

Una búsqueda que me ha llegado. Longitud de la parte decimal de un número con SAS. Nos sirve para recordar (me gusta insistir en el tema) como transformamos números en caracteres con SAS. La función PUT es la que realiza esta tarea:

data _null_;

y=67.34123432;

x=length(scan(put(y,best32.),2,"."));

put x=;

run;

Transformamos un número a texto. Con SCAN buscamos la parte decimal puesto que el separador será el . Y con LENGTH tenemos la longitud resultante del texto obtenido. No sé para que puede servir esto pero ahí os planteo como se resuelve.

Macros (fáciles) de SAS. Busca duplicados

Una macro muy sencilla que ha aparecido en un programa de funcionalidades y que busca registros duplicados en tablas SAS. Es muy sencilla y a alguien puede serle útil y para eso estamos, para compartir conocimientos aunque sean sencillos. Pocos somos los que compartimos nuestro conocimiento y encima poniendo nuestro dinero, en fin, que me distraigo del tema.

%macro busca_duplicados ( dataset, campo);

proc sql;

create table duplicados (where=(frec>1)) as select

&campo.,

count(*) as frec

from &dataset.

group by 1;

quit;

%mend;

No pongo ni ejemplo de uso, muy fácil. Pero ya verás como alguien le saca partido. Y todo esto de forma altruista, insisto, que si no me valoro yo no me valora nadie. Saludos.

La función LAG de SAS

La función LAG de SAS nos devuelve el valor de la observación n-n de la variable indicada. Me explico con un ejemplo:

data lagn;

do i=1 to 10;

lag_1=lag(i);

lag_2=lag2(i);

lag_3=lag3(i);

lag_4=lag4(i);

lag_5=lag5(i);

lag_6=lag6(i);

output;end;

run;

Esto produce:

lag.PNG
LAG(i) nos da el valor de i para la observación anterior, LAG2(i) nos da el valor de las 2 observaciones anteriores,… En el caso de encontrarnos en las primeras observaciones el valor que devuelve es el missing. Con ella podemos evitar trabajar con RETAIN a la hora de hacer sumas acumuladas:

Creando un mapa en Excel con archivos SVG

Aunque me lo agradezcan poco el mapa por comunidades de Excel está teniendo un gran éxito. Mientras preparo un mapa por provincias en Excel he elaborado el siguiente tutorial para crear mapas en Excel a partir de archivos SVG. El punto de partida, disponer de Inkscape software libre para la elaboración de dibujos y Excel. Podemos buscar mapas en la wikipedia, en este caso mapa por provincias de España. Se trata de utilizar ese archivo svg y crear un Excel con objetos de ms-office que provienen del archivo svg que hemos abierto con el Inkscape. Juntamos las piezas del puzle y ya podemos trabajar con el mapa.

Macros SAS. Dataset a data frame R

Voy a presentaros la versión Beta de la macro de SAS que genera data frames a partir de una tabla SAS en Windows, la versión en Linux me la ahorraré hasta el día que pueda instalar SAS en mi máquina virtual. La macro la iré mejorando y evolucionando, probablemente estas mejoras no las colgaré y no retome el hilo hasta que tenga una V1. El tema es sencillo y anteriormente ya hice mención a este método pero ahora doy una vuelta de tuerca y directamente creamos data frames a partir de data sets. Os pongo el total del código y comentaré los pasos más interesantes, por supuesto es mejorable. Lo que no puedo asegurar es si funciona bajo WPS porque no me han renovado la licencia. Todo el código seguido:

Trucos R. Leer archivos XML con R

Un truco de R práctico que busca la colaboración de los lectores para mejorarlo. Se trata de leer ficheros xml con R. Los más asiduos ya sabéis que paquete voy a emplear, el XML. En los últimos tiempos la sentencia require(XML) aparece al principio de casi todos mis códigos en el Tinn-R. El ejemplo que ilustrará el truco lee de la BBDD del banco mundial en español el indicador de emisiones de CO2 en toneladas por habitante y año. La sintaxis es de este modo:

Trucos SAS. Mejor que hash IN para cruzar tablas

El otro día Fernando comentó que los cruces de tablas más rápidos entre tablas grandes y tablas pequeñas son las sentencias condicionales sobre listas. Tiene razón. Es una práctica muy habitual en SAS cuando leemos tablas de Oracle la ralización de listas, esto derivará en otro truco SAS en breves días. El caso es que me gustaría que probárais este código:

data grande;

do i=1 to 20000000;

idcliente=int(ranuni(0)*1000000);

drop i;

output;

end;

run;

*CONJUNTO DE DATOS PEQUEÑO, NO TIENE

 REGISTROS DUPLICADOS;

data pequenio;

do i=1 to 2000000;

idcliente=int(ranuni(34)*1000000);

drop i;

if mod(idcliente,1132)=0 then output;

end;

run;

proc sort data=pequenio nodupkey; by idcliente;quit;

*;

proc sql noprint;

select idcliente into:lista separated by " "

from pequenio ;

quit;

*;

data machea5;

set grande;

if idcliente in (&lista.);

run;

Bueno, el tiempo de ejecución de este cruce es de 3 segundos. Mejora a las soluciones planteadas el otro día y sobre todo es un código fácil, muy fácil. Se trata de crear listas de macrovariables y realizar un paso data con una sentencia condicional. Tiene un problema, el tamaño máximo que nos permite una macrovariable. Y en este punto continúa el truco SAS. ¿Cúal es el tamaño máximo que puede tener una macrovariable? 64K, 65534 characters. Tenemos que evitar a toda costa este error: ERROR: The length of the value of the macro variable LISTA (70356) exceeds the maximum length (65534). The value has been truncated to 65534 characters. Para evitar este problema podemos realizar el siguiente planteamiento: 65.000/la longitud del campo de cruce, en el caso del ejemplo: 65.000/8 = 8.000 más o menos. Hacemos una prueba:

Trucos R. Establecer la configuración local de una fecha

Cuando manejamos datos las fechas nos producen muchos quebraderos de cabeza, por ejemplo cuando tenemos que transformar un caracter a fecha. En mi opinión R es una de las herramientas las flexibles y rápidas para trabajar con fechas, claro que acostumbrado a SAS cualquier otra herramienta me parece perfecta. A lo que vamos, imaginemos la siguiente situación :

?as.Date

x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")

z <- as.Date(x, "%d%b%Y")

z

[1] NA NA "1960-03-31" "1960-07-30"

Se trata de transformar un texto a fecha en R. El formato del texto es d mes en inglés año con 4 cifras. Para transformar a fecha tenemos la función as.Date que recibe como parámetros el objeto y el formato de la fecha, el más habitual sería %d/%m/%Y 10/09/1976. Para meses en formato nombre empleamos %b pero en este caso «1jan1960» nos produce un valor perdido sin embargo «31mar1960» si se transforma correctamente ¿Por qué motivo sucede esto?

Trucos SAS. Porque hay que usar objetos hash

Quiero trabajar un poco con objetos hash en SAS. Pero antes quería demostraros con una comparativa de código muy sencilla y muy rápida la necesidad de trabajar con estos objetos en SAS. La problemática es muy habitual en nuestro trabajo diario. Tenemos una tabla SAS muy grande, con millones de registros y tenemos que cruzarla con otra tabla SAS muy pequeña para quedarnos sólo con los registros que aparezcan en la tabla pequeña. Tenemos unos clientes que han recibido un contacto comercial y hemos de quedarnos con sus saldos históricos en determinados productos. Veamos los distintos métodos que planteo para machear registros, conjuntos de datos de partida: