Me han llegado algunas cuestiones sobre el uso de DROP/KEEP y a raiz de ello me he decidido a hacer un mensaje sencillo para que los usuarios menos avanzados de SAS puedan entender su funcionamiento. Sé que muchos lectores son expertos programadores pero también es necesario tener un rincón con código SAS menos avanzado para aquellos que se estén acercando a esta programación. En este caso partimos de una tabla de datos aleatorios con 102 variables y 10.000 observaciones que generamos mediante el siguiente programa SAS:
data uno;
array variab (100);
do j=1 to 10000;
do i=1 to 100;
variab(i)=rand("uniform")*100;
end;
output;
end;
run;
La idea es quedarnos sólo con las variables j variab1, variab10 hasta variab19 y variab100. Lo más habitual es emplear keep como una instrucción dentro de paso DATA:
data sub1;
set uno;
keep j variab1 variab10--variab19 var100;
run;
Con — indicamos un rango de variables dentro del dataset para ahorrarnos escribirlas todas, además añadimos las restantes variables necesarias. Pero keep también puede aparecer como una opción de lectura o de escritura de un conjunto de datos SAS. Como opción de escritura:
data sub3 (keep=j variab1 variab10--variab19 variab100);
set uno;
run;
Esto nos permite optimizar el espacio a la hora de generar un dataset, pero como más podemos optimizar nuestra ejecución de SAS es empleando keep o drop como opción de lectura:
data sub2;
set uno (keep=j variab1 variab10--variab19 variab100);
run;
Sólo leeremos de UNO las variables que nos interesan, esto puede hacer que un programa SAS sea mucho más rápido y nosotros mucho más eficientes para que nuestro responsable nos pida mucho más trabajo. Otra forma de seleccionar variables que tienen un nombre con una raiz similar es emplear en DROP/KEEP el signo de puntuación : con ello indicamos a SAS que deseamos todas las variables que empiecen por un sufijo, por ejemplo:
data sub4;
set uno;
keep j variab1:;
run;
Esto equivale a los códigos anteriormente vistos ya que nos quedamos con todas las variables que empiezan por variab1. Además del — contamos con los : para ahorrarnos mucho código y ser eficientes. Y si somos más eficientes podemos trabajar más o visitar esta magnífica web. Por supuesto todo lo anterior se puede aplicar a DROP para eliminar variables. Cualquier duda o sugerencia estoy en rvaquerizo@analisisydecision.es
Me alegro mucho de que hayas dedicado atención al comando DROP. Todo programador en SAS debería usarlo al menos 20 veces al día (los programadores nóveles, 30).
La mayor parte de los problemas de rendimiento que he visto en aplicaciones de SAS se debe a que los programadores no siguen a rajatabla tan higiénico criterio.
Felicidades por el blog, está bueno, y este tipo de post es bueno para los que tenemos poco conocimientos del SAS .
Como esta entrada es para los newies en SAS yo comparto una duda que tengo, en SAS, esposible leer varios archivos de golpe con el infile, o se hace de otra manera, es decir, si tengo 25 archivos en una carpeta y lo quiero leer con el infile, ¿hay alguna forma de que los lea todos sin que le tenga que decir el nombre de cada uno de los archivos?.
Bueno es todo y adelante con este tipo de blogs.
Hola Pablo, hay algunas formas de hacer lo que preguntas pero no las considero precisamente para newbies, requiere un poco el uso de macros y funciones del sistema. En este enlace que te pongo puedes ver una macro (drive) que podrías utilizar ir leyendo los archivos con un bucle si tienen todos el mismo formato.
http://www.listserv.uga.edu/cgi-bin/wa?A2=ind0612a&L=sas-l&P=60974
Recuerdo haber visto en la página de support de SAS la misma macro, pero no encuentro el enlace. De todas formas el que te pongo es un corta y pega de la macro que te comento.
La idea sería modificar esta macro incluyendo un bloque que utilice el nombre del archivo para leerlo e ir haciendo appends (la macro tal cual solo imprime los nombres de los ficheros en el log) o almacenándolo como uno quiera.
Pablo,
Como te ha dicho Fernando lo que tienes que hacer es importarlo uno a uno y unirlo en un paso final. Automatizar el proceso te llevaría mucho esfuerzo si te estás iniciando en SAS.
Bien explicado, un articulo fundamental para usar los pasos data eficientemente.
Yo añadiría, si el orden de los campos (variables) que queremos extraer de la tabla original son: variab1 .. variab10 .. variab19 .. variab100 y resulta que queremos que aparezca primero el variab100 y luego el resto en nuestro data sub2 (puesto que el ‘keep’ solo dice que variable nos vamos a quedar pero no en que orden):
data sub2;
variab100=.;
set uno (keep=j variab1 variab10–variab19 variab100);
run;
De esta manera, al crear la variab100 como nueva variable antes de ‘colocar’ las variables
del data uno, la variable100 tiene orden de preferencia y queda en primera posición resultando en este orden:
variab100 variab1 variab10 .. variab19 J
de lo contrario habrian salido:
variab1 variab10 .. variab19 variab100 j
manteniendo el orden original de las variables del data uno.
Dani Fernández.
Dep. Control de Gestión y Análisis de la Información.
Consorci Sanitari de Terrassa (Hospital de Terrassa), Barcelona.
Yo para hacer eso prefiero utilizar el retain:
data sub2;
retain variab100;
set uno(keep= ….);
run;
Pero no se si hay alguna implicación técnica que diga que es mejor un método u otro.
Que tal, por favor, me gustaría me dijeras como elimina el signo de una variable númerica (ejemp. -3,280)
Gracias, saludos
Emplea la función abs() para quedarte con el valor absoluto de un número.
Hola,
¿sabésia cómom podría construir una macro que automatice la lectura de un fichero?, a ser posible fichero host.
Gracias.
Saludos.
Básicamente haciendo el códgio que lea el fichero, y metiéndolo en una macro, sustituyendo por macrovariables todo aquello que quieras que se le pase como parámetro…
Hola. Gracias por vuestras aportaciones. ¿Cómo podría hacer para forzar el orden de extracción de las variables de una tabla (ver Dani Fernández, julio 2009) para que fuera, por ejemplo, V1, V3, V5, V2, V4, V6?
María, he creado una entrada para dar respuesta a tu duda.
Hola, muy interesante la explicación.
Si quisieramos encontrar el valor mínimo de toda la matriz (100 x 10000), haríamos otra vez un array para encontrar el valor mínimo y que recorriera todas las varables? habría una forma más rápida de hacerlo? porque en el caso de ser datasets más pesados,se retardaría mucho, no?
Saludos y gracias!