SAS

Ayudadme. Importar a SAS texto con comillas

Hoy sois vosotros los que tenéis que ayudar al dinosaurio. Ya no estoy para estas cosas. Tengo un problema. Fichero de texto separado por ; típico csv de toda la vida. Este fichero de texto contiene diversos campos que a mis efectos son de texto. Si abrimos el fichero con una hoja de cálculo tendríamos:

Pues bien, a la hora de importar unos datos con esa estructura desde SAS no soy capaz de que Dato2 siga conservando las comillas. Con IMPORT tampoco me funciona. El código sería algo parecido a esto:

App de SAS para tomar decisiones en base al Big Data

Os presento una app que ha lanzado SAS para emplear el Big Data en la toma de decisiones: https://play.google.com/store/apps/details?id=com.sas.bigdataoverload&feature=more_from_developer#?t=W10. Me la ha mandado mi amigo Pepelu. En cuanto pueda me la descargo y comienzo a jugar a ver cómo se me da esto del análisis de grandes volúmenes de información que ahora llaman Big Data e incluso se pueden leer artículos sobre el tema en la prensa más generalista.

Con la de años que llevan algunos haciendo esto…

Intervalos en SAS con PROC FORMAT

El uso de formatos en SAS para la creación de intervalos puede ahorrarnos tanto escritura de código como espacio en nuestros conjuntos de datos SAS. Una vez que nos familiaricemos con ellos evitaremos la creación de sentencias IF anidadas y generar nuevas variables de texto de gran longitud en nuestro dataset. Sin embargo siempre me plantean la misma cuestión, ¿por dónde están cerrados los intervalos en un formato? Hoy vamos a generar una serie de ejemplos para analizar este tema. Partimos de un conjunto de datos aleatorio con una variable de poisson con media 18:

Macros SAS. Contar las palabras de una macro variable

Una macro de SAS interesante que nos permite ahorrar código. Dada una macro variable necesitamos contar el número de palabras que tiene esta macro variable. Para ello vamos a crear una función con código macro:

%let texto = uno dos tres;

%macro cuenta(mv);
%eval(%sysfunc(length(%cmpres(&mv.),%str( ))) - %length(&mv.) + 1)
%mend;

%put La Macrovariable Texto tiene %cuenta(&texto.) palabras;

Vemos que la macro variable texto tiene tres palabras y necesitamos contabilizarlas para automatizar un código. La propuesta que se plantea es el cálculo de la longitud de la macro sin espacios frente a la longitud de la macro variable con espacios. La diferencia más uno será el número de palabras de nuestro texto. Como aspectos interesantes tenéis el uso de %str( ) , %cmpres y como se juega con %sysfunc para evitar algún que otro problema. Esta macro tiene sus problemas, no pongáis más de dos espacios que la volvéis loca. Pero puede resultar muy útil para determinadas cosas. Saludos.

Parámetro asociado a una Poisson con SAS

Mirad que he visto datos en mi vida. Y esos datos siguen muchas distribuciones. Y una de las distribuciones más habituales con las que me he encontrado es la distribución de poisson. Esta distribución tiene una característica muy interesante: la varianza es igual que la media. Y si la varianza no es igual a la media tenemos distribuciones de poisson sobredispersa o poisson infradispersa con propiedades muy interesantes y que se emplea mucho en el ámbito actuarial, aunque tendremos eventos con una distribución de poisson cuando estamos hablando de eventos independientes en intervalos de tiempo. No soy yo el más adecuado para escribir sobre el modelo matemático que tienen detrás estas distribuciones, pero si me gustaría mostraros como hacer mediante SAS con el PROC GENMOD algo tan básico como obtener el parámetro asociado a mi distribución de poisson y el intervalo de confianza al 95% para este parámetro. Vale que el parámetro es la media pero tengo que escribiros un código SAS importante ¿Y cómo lo calculamos?

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.

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.

Truco SAS. Macro número de días de un año

Macro de SAS que te dice el número de días que tiene un año.

%macro dias_anio(anio);

"31DEC&anio."d-"01JAN&anio."d+1

%mend;

A lo mejor ya la he puesto, no me lo tengáis en cuenta.

Trucos SAS. Particionar y exportar a texto un dataset

Duda que plantea David. Exporta a csv una tabla SAS en varias partes. Ya habrá tiempo para comentarlo:

*TABLA SAS DE EJEMPLO;

data total;

do i=1 to 10000;

importe=ranuni(8)*100;

output;

end;

run;

*MACRO QUE RECORRE LA TABLA, PARTE Y EXPORTA CADA PARTE
NECESITA EL CONJUNTO DE DATOS Y EL TAMAÑO DE CADA PARTE;
%macro parte(ds, tamanio);
%do i = 1 %to 10000 %by &tamanio.;
data parte;
set &ds. (firstobs = &i. obs = %eval(&i. + &tamanio.));
run;