La macro iterlist para automatizar código SAS

Impresionante macro de SAS que nos puede ahorrar picar mucho mucho código SAS. La macro se llama iterlist y la he encontrado en este enlace. Es código SAS muy avanzado:

%macro iterlist(code =,list =);
%*** ASSIGN EACH ITEM IN THE LIST TO AN INDEXED MACRO VARIABLE &&ITEM&I ;
%let i = 1;
%do %while (%cmpres(%scan(&list., &i.)) ne );
%let item&i. = %cmpres(%scan(&list., &i.));
%let i = %eval((&i. + 1);
%end;
%*** STORE THE COUNT OF THE NUMBER OF ITEMS IN A MACRO VARIABLE: &CNTITEM;
%let cntitem = %eval((&i. - 1);
%*** EXPRESS CODE, REPLACING TOKENS WITH ELEMENTS OF THE LIST, IN SEQUENCE;
%do i = 1 %to &cntitem.;
%let codeprp = %qsysfunc(tranwrd(&code.,?,%nrstr(&&item&i..)));
%unquote(&codeprp.)
%end;
%mend iterlist;

El funcionamiento es muy complejo, destacaría el uso de %qsysfunc. El caso es que nos permite poner listas de código. Imaginemos que tenemos que hacer la siguiente tarea:

Macros SAS. Pasar de texto a numérico

“Pasar de texto a número en SAS”. Una de las búsquedas que más recibe esta web. Ya hay monográficos, trucos, artículos,… al respecto. Pero faltaba una macro que espero os ayude. Es una macro muy básica pero que permite pasar textos con números en formato europeo o en formato americano. La macro:

%macro texto_numero(varib_ini=, varib_fin=,europeo=0);
vaux=&varib_ini.;
drop vaux;
%if &europeo. %then %do;
vaux = compress(vaux,".");
%end;

%if &europeo. %then %do;
vaux = tranwrd(vaux,",",".");
%end;

&varib_fin. = input(vaux * 1,best12.);
%mend;

Breve descipción. La variable inicial (parámetro varib_ini) será la cadena de texto que deseamos pasar a número. La variable final (parámetro varib_fin) será el nombre de la variable numérica. Si deseamos conservar el nombre tenemos que jugar con rename como opción de lectura o escritura del paso data. Estoy estudiando otra macro más avanzada para realizar este trabajo. El parámetro europeo=0 es el que nos indica si el número que transformamos tiene formato europeo o no. La macro necesita una variable auxiliar para realizar las transformaciones necesarias en el caso de ser un número en formato europeo. Una vez está el número en formato americano realizamos la transformación sobre la variable final con input, el formato que ponemos es best12.

Trucos Excel. Unir todos los excel en uno, versión muy mejorada

El amigo @jose nos envía una nueva versión de la macro Excel que nos permite unir varios excel en uno. En este enlace en formato RAR tenéis un ejemplo de funcionamiento donde el libro de Excel más importante es UNIR.XLSM Las instrucciones de uso son:

  1. Ponemos todos los Excel que deseemos unir en un directorio
  2. Ponemos UNIR.XLSM en ese directorio
  3. Abrimos UNIR.XLSM y simplemente pulsamos el botón
  4. Tenemos un nuevo libro llamado UNIDOS.XLS

Así de sencillo. El código que emplea la macro es visible, su autor no pone problemas. Muchas gracias @jose por esta macro tan sencilla y tan práctica, seguro que muchos de vosotros la encontraréis muy útil. Yo la encuentro genial. Saludos.

Cuánto dinero pierdo jugando a la lotería. Una simulación poco seria con R

Esta pantalla es muy habitual en mi televisor todos los jueves por la noche. Son los resultados de la Lotería Nacional de España, el sorteo de los jueves. Mi mujer insiste en comprar lotería para dejar de ser pobres. No es una buena opción. Aunque por lo menos ahora compramos lotería nacional. Antes jugábamos a eso de la Bonoloto, las probabilidades de que te toque son menores que la cantidad de sustancias dopantes que le encontraron al gran Alberto Contador. Eso lo entendió, pero había que jugar. ¿Y cuánto nos cuesta jugar?

Macro SAS. Variables de un dataset en una macro variable

Hoy os presento una macro de SAS que nos permite recoger en una macro variable las variables de un conjunto de datos SAS. Tiene como particularidad que nos sirve para seleccionar aquellas variables que tienen un determinado patrón, del tipo consumo2010, consumo2011,… Es un código un poco más complejo de lo habitual pero tiene aspectos interesantes:

options mlogic mprint;
%macro lista_variables (ds= , nombre_mv= , patron=);
*ES NECESARIO QUE LA MACROV FINAL SEA GLOBAL;
%global &nombre_mv.;
*PUEDE SER QUE LA LIBRERIA SEA WORK O PERMANENTE;
	data _null_;
	length lib tab $255.;
	if index("&ds.",".")=0 then lib="WORK";
	else lib=scan("&ds.",1,".") ; put lib=;
	call symput('libreria',lib);
	tab=scan("&ds.",2,".") ;
	call symput('tabla',tab);
	run;
*BUSCAMOS EN DICTIONARY DE SAS;
	proc sql noprint;
	select compress(name) into:&nombre_mv. separated by " "
	from sashelp.vcolumn
where libname=upcase("&libreria.") and memname=upcase("&tabla.") and
/*PODEMOS APLICAR UN PATRON*/
	upcase(name) like '%'||"%upcase(&patron.)"||'%';
	quit;
%mend;

El elemento principal de esta macro es una consulta a una de las tablas DICTIONARY de SAS. O mejor dicho, a una de las vistas que tenemos en SASHELP. Siempre he prefererido consultar las vistas de SASHELP. La vista consultada es VCOLUMN de donde extraemos la columna NAME y como condicionantes pasamos la librería en LIBNAME y el nombre de la tabla de la que deseamos obtener las variables en MEMNAME. Como particularidad podemos aplicar patrones.

Macro (fácil) de SAS. Longitud de la parte decimal de un número

Muy sencillo, vemos el programa y posteriormente lo transformamos en una macro de SAS:

data aleat;

do i = 1 to 100;

aleatorio=ranuni(8)*1000;

largo_decimal = length(scan(put(aleatorio,best32.),2,"."));

output;

end;

run;

Sencillo, pasamos de número a carácter con PUT y buscamos el punto con SCAN, extraemos la segunda parte del carácter separado por punto y vemos su longitud. Esto pasado a una macro:

%macro largo_decimal(num);

length(scan(put(&num.,best32.),2,"."))

%mend;

data aleat;

do i = 1 to 100;

aleatorio=ranuni(8)*1000;

largo_decimal = %largo_decimal(aleatorio);

output;

end;

run;

Sencillo, a mi hoy me ha sido útil. Saludos.

Truco SAS. Un vistazo a ficheros planos muy grandes

Alguna vez no habéis podido abrir un fichero de texto muy grande para comprobar si tiene cabeceras o conocer el separador de campos. Es habitual emplear para esto el gran UltraEdit. Pero podemos emplear el PROC FSLIST de SAS para poder hacer esta tarea y se nos abrirá de inmediato una vista del fichero en una ventana de nuestra sesión SAS. La sintaxis muy sencilla:

proc fslist fileref="Z:\temp\archivo_enorme.txt";

quit;

Este sencillo código nos abrirá las primeras líneas del archivo en un instante y así podremos comprobar si tiene cabeceras o el separador que utiliza. Esto nos facilitaría la importación del fichero a tabla SAS. Saludos.

Fechas importantes para las IV Jornadas de Usuarios de R

R

Hay que tener en cuenta las siguientes fechas para todos aquellos que deseéis participar:

  • 16 de septiembre de 2012 Fecha límite para el envío de abstracts
  • 21 de octubre de 2012 Fecha límite para la aceptación de abstracts

Las IV Jornadas de Usuarios de R tendrán lugar en el CREAL los días 15 y 16 de noviembre de 2012. Hay en marcha una competición de análisis de datos con R, cuando tenga conocimiento de las bases y las fechas os las comunico.

Trucos Excel. Gráficos dot plot, representando un ranking gráficamente

Los gráficos de puntos son muy prácticos para representar de una forma visual rankings (por ejemplo). En Excel su realización no es inmediata como con otras herramientas (R por ejemplo). Para ilustrar el ejemplo se van a presentar los 20 primeros puestos de la lista TIOBE de mayo de 2012 (la entrada estaba en la nevera). Entramos en la lista y sin más copiamos y pegamos los datos de tabla HTML a tabla Excel:

Solventamos los peligros del análisis cluster con SVM

Retomamos un asunto tratado en días anteriores, los peligros de realizar un análisis de agrupamiento basado en las distancias entre observaciones. ¿Cómo podemos evitar este problema? Empleando máquinas de vectores de soporte, traducción de Support Vector Machines (SVM). Esta técnica de clasificación de la que ya hablamos en otra entrada nos permite separar observaciones en base la creación de hiperplanos que las separan. Una función kernel será la que nos permita crear estos hiperplanos, en el caso que nos ocupa tenemos sólo dos variables, necesitamos crear líneas de separación entre observaciones. En la red tenéis una gran cantidad de artículos sobre estas técnicas.