introduccion a sas

78
© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected] Introducción a SAS Raúl Vaquerizo 2007

Upload: macielgarmendia

Post on 26-Jul-2015

1.342 views

Category:

Documents


19 download

TRANSCRIPT

Page 1: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Introducción a SAS Raúl Vaquerizo 2007

Page 2: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Contenido: 1. Componentes del sistema SAS ................................................................................ 3 2. Explorar el entorno de SAS..................................................................................... 4 3. Introducción a los programas SAS ........................................................................... 7

3.1 Crear y ejecutar sentencias SAS ......................................................................... 7 3.2 Reglas básicas de SAS....................................................................................... 8 3.3 Ejecuciones remotas de SAS............................................................................... 8

4. Librerías SAS........................................................................................................ 8 4.1 Librerías SAS temporales ................................................................................... 9 4.2 Librerías SAS permanentes ................................................................................ 9

4.2.1 Librerías en local ......................................................................................... 9 4.2.2 Librerías en servidor .................................................................................... 9

5. Conjuntos de datos SAS. El paso DATA....................................................................10 5.1 Leer ficheros de datos con SAS. Creación de datasets ...........................................10

5.1.1 Ficheros SAS de entrada manual ..................................................................11 5.1.2 Lectura de ficheros de texto.........................................................................11 5.1.3 Lectura de otros ficheros SAS.......................................................................14

5.2 Variables ........................................................................................................17 5.2.1 Variables numéricas....................................................................................17 5.2.2 Variables fecha ..........................................................................................19 5.2.3 Variables alfanuméricas...............................................................................20 5.2.4 Formatos de variables.................................................................................23 5.2.5 Variables dentro del paso DATA....................................................................24

5.3 Observaciones.................................................................................................27 6. Uniones de conjuntos de datos SAS ........................................................................31

6.1 Tipos de uniones..............................................................................................31 6.2 Uniones habituales de tablas .............................................................................34

6.2.1 Añadir nuevas variables a un conjunto de datos SAS .......................................34 6.2.2 Búsqueda de observaciones coincidentes .......................................................36

7. Procedimientos básicos de SAS ..............................................................................39 7.1 PROC SORT ....................................................................................................39 7.2 PROC PRINT....................................................................................................39 7.3 PROC SUMMARY/MEANS:..................................................................................40 7.4 PROC FREQ.....................................................................................................44 7.5 PROC DATASETS .............................................................................................46 7.6 PROC IMPORT/EXPORT .....................................................................................49 7.7 PROC TRANSPOSE ...........................................................................................50 7.8 PROC UNIVARIATE...........................................................................................52

8. PROC SQL ...........................................................................................................60 8.1 Consultas de selección......................................................................................61

8.1.1 “Bloques” que componen una consulta ..........................................................61 8.1.2 Campos de selección condicionales (CASE).....................................................64 8.1.3 Uso de sentencias lógicas y condicionales ......................................................66

8.2 Consultas de creación de tablas con PROC SQL ....................................................68 8.3 Uniones de tablas ............................................................................................71

8.3.1 Uniones verticales ......................................................................................71 8.3.2 Uniones horizontales (joins).........................................................................73

Page 3: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

1. Componentes del sistema SAS SAS nació como una herramienta de análisis estadístico. En realidad es el acrónimo de Statistical Analysis System pero desde 2001 sus soluciones van más encaminadas al Business Inteligence que es una disciplina a caballo entre la informática, las matemáticas y la gestión empresarial. SAS está compuesto de una plataforma BASE a la cual se le añaden distintos módulos. Los módulos más destacados de SAS son: SAS/ACCESS Interfase a otros formatos de ficheros SAS/AF Lenguaje para el diseño de aplicaciones SAS SAS/ASSIST Asistencia para el uso de SAS SAS/CONNECT Conjunto de herramientas cliente/servidor SAS/EIS Permite construir Bases de datos multidimensionales MDDB y relacionales RDBMS SAS/ETS Análisis de Series Temporales SAS/FSP Facilidades para la entrada de datos de forma interactiva SAS/GIS GIS (Sistema de Información Geográfica) interactivo con SAS SAS/GRAPH Módulo gráfico SAS/IML Manipulación de matrices SAS/INSIGHT Herramienta para explorar y analizar datos SAS/MDDB Trabajo con Bases de datos Multidimensionales SAS/ODBC Conexiones ODBC SAS/OR Para resolver problemas de optimización SAS/QC Control de Calidad SAS/SPECTRAVIEW Visualización de datos cómo representaciones gráficas SAS/STAT Análisis Estadísticos SAS/IntrNet Permite a los usuarios ejecutar programas desde un navegador Otros Productos SAS SAS Enterprise Miner DataMining SAS Enterprise Guide Facilidad para el análisis estadístico. La estructura más habitual en las empresas es: BASE + STAT + GRAPH en los equipos locales y, en el caso de disponer de SAS en servidor, SAS CONNECT. En el servidor, que puede ser UNIX o Windows, los módulos habituales también son BASE, STAT, GRAPH y CONNECT. Otro elemento muy habitual es el Enterprise Guide que es una herramienta para facilitar la programación en SAS.

Page 4: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

2. Explorar el entorno de SAS Al abrir SAS nos encontramos con el siguiente interfaz:

SAS es una aplicación en la que el trabajo se realiza mediante programación por lo que nuestra ventana habitual de trabajo será el Editor Avanzado. Esta ventana es un editor de texto (similar a un block de notas) que dispone de una ayuda a la programación mediante código semafórico, desde aquí ejecutaremos toda la sintaxis de SAS. Otra ventana fundamental para nuestro trabajo será la Log, allí podremos ver si nuestro programa se ha ejecutado correctamente. Si nuestra ejecución genera una salida en modo texto entonces tenemos la ventana Output. En la parte izquierda de nuestro interfaz tenemos 2 ventanas solapadas. El explorador es un navegador de archivos pero fundamentalmente lo emplearemos para navegar por librerías SAS. Este explorador se puede configurar a nuestro deseo a través del menú ver:

Page 5: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

El menú archivo:

El menú edición:

El menú ver:

Page 6: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

El menú ejecutar:

El menú soluciones:

El menú ventana:

Herramientas: Cada ventana tiene sus propias herramientas. Desde los exploradores tenemos:

Son herramientas habituales para el uso. Por orden son: Subir un nivel, nuevo objeto, abrir, guardar, cortar, copiar, pegar, deshacer, eliminar, ver detalles, mostrar árbol, nueva librería, abrir explorador como ventana, ayuda. Desde el editor, el log y output podemos ver:

Page 7: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Por orden: Limpiar pantalla, abrir, guardar, vista previa para impresión, cortar, copiar, pegar, deshacer, nueva librería, explorador, ejecutar, parar ejecución y ayuda. Todos estos menús son personalizables. Además habitualmente se emplean teclas que tienen asociadas funciones que nos facilitan las labores más habituales. Para ver estas teclas nos situamos en la barra de comandos y escribimos keys:

Las definiciones son, en realidad, los mandatos que ejecutan.

3. Introducción a los programas SAS Los programas SAS se dividen en dos grupos: pasos DATA y pasos PROC. El paso DATA crea o transforma conjuntos de datos SAS. Los procedimientos o pasos PROC no transforman conjuntos de datos SAS, realizan análisis, tablas, cálculos estadísticos,...

3.1 Crear y ejecutar sentencias SAS Los programas SAS se crean y se ejecutan desde el editor avanzado. Se puede ejecutar un programa entero o bien selecciones de programa. Habitualmente nuestras ejecuciones generarán conjuntos de datos SAS o salidas de información. Tras cada ejecución comprobaremos si se ha realizado correctamente visualizando la ventana log. Esta ventana es un debugger donde comprobaremos cada paso DATA o procedimiento. /*PROGRAMA 1*/ data uno; input x $ y; cards; 1 34 2 54 3 78 ; run;

Page 8: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

/* Sirve para abrir comentarios, */ los cierra. Es muy práctico comentar nuestros programas. DATA crea un conjunto de datos SAS, en este caso llamado uno. Todas nuestras sentencias SAS finalizarán con ; si lo omitimos SAS nos devolverá un error. Con INPUT le indicamos a SAS que cree dos variables, si la variable va precedida de $ entonces es una variable alfanumérica. SAS distingue dos tipos de variables, numéricas y alfanuméricas. Con CARDS introducimos los datos manualmente y tras introducirlos ponemos ;. Por último RUN finaliza la ejecución. Es imprescindible marcarle a SAS cuando finaliza la ejecución.

Para ejecutar los programas es necesario pulsar el botón , ejecutar desde el menú o escribir SUBMIT en la línea de comandos.

3.2 Reglas básicas de SAS Los conjuntos de datos SAS, las librerías y las variables han de empezar por _ o letras A--Z . Tampoco pueden tener espacios en blanco. No pueden exceder de 32 caracteres. Las librerías que contienen programas SAS nunca podrán exceder en su nombre de 8 caracteres.

3.3 Ejecuciones remotas de SAS En el caso de trabajar en una estructura cliente servidor será necesario conectarse e indicarle a SAS que se trata de una ejecución remota: /*PROGRAMA 1*/ signon /*SERVIDOR*/; rsubmit; data uno; input x $ y; cards; 1 34 2 54 3 78 ; run; endrsubmit; signoff;

4. Librerías SAS El elemento principal de SAS son los conjuntos de datos. Éstos pueden ser almacenados en librerías temporales o en librerías permanentes. Una librería es un conjunto de elementos de SAS como puedan ser: catálogos, vistas, formularios,... En todo momento nos centraremos en los conjuntos de datos. Las librerías, al final, son directorios con elementos de SAS. Para navegar entre ellas emplearemos el explorador. Al arrancar nuestra sesión de SAS deberemos tener al menos las siguientes librerías:

Page 9: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Para movernos entre ellas haremos doble click y si necesitamos subir niveles emplearemos el

botón de la barra de herramientas Se pueden obtener varias vistas al igual que un explorador de Windows habitual. La librería Maps contiene la colección de mapas de SAS. Sashelp y Sasuser son librerías del sistema. La más importante de éstas es la librería temporal WORK. Como regla básica remarcar que el nombre de una librería SAS nunca podrá exceder de 8 caracteres ni tener espacios en blanco.

4.1 Librerías SAS temporales Cada sesión de SAS tiene su librería temporal conocida como WORK. Esta librería sólo existirá mientras dure nuestra sesión de SAS. Cuando cerremos perderemos los conjuntos de datos que no hayamos dejado en una librería permanente. La librería WORK estará ubicada en un directorio previamente asignado por el archivo de configuración. La emplearemos para ubicar todas aquellas tablas que, por su naturaleza, no necesitamos al finalizar nuestra sesión.

4.2 Librerías SAS permanentes Son los directorios de nuestro PC o del servidor donde ubicamos conjuntos de datos SAS.

4.2.1 Librerías en local

La sintaxis necesaria para crear una librería SAS en nuestro PC (en local) es: libname permanen "C:\SAS_sesiones"; Si ejecutamos obtendremos en la ventana Log:

Es una librería SAS con una ubicación en C:\SAS_SESIONES. En el explorador podremos ver:

4.2.2 Librerías en servidor

Para crear librerías en servidor es necesario conocer la ubicación remota: rsubmit; libname librem "\ubicacion\remota" /*ESTE DIRECTORIO EXISTE EN EL SERVIDOR*/; endrsubmit; libname librem remote server=servidor slibref=librem; En el explorador veríamos las librerías remotas con un icono distinto:

Page 10: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Habitualmente las librerías del servidor están asignadas al inicio de la sesión SAS por los administradores de los servidores.

5. Conjuntos de datos SAS. El paso DATA El elemento principal de trabajo de SAS son los conjuntos de datos, se componen de datos, observaciones y variables. Un conjunto de datos SAS es una tabla de datos con determinada información. Se almacenan en librerías SAS y el fichero físico tiene la extensión *.sas7bdat, si vemos el archivo con el explorador de Windows veremos:

Si deseamos abrir un conjunto de datos haremos doble clic sobre el conjunto de datos que podremos ver en el explorador de librerías, inmediatamente aparecerá una ventana:

Desde esta vista podemos navegar por nuestro conjunto de datos de forma similar a como lo haríamos en una hoja de cálculo pero con algunas limitaciones. Como regla básica los nombres nunca podrán exceder de 32 caracteres ni tener espacios en blanco. El elemento principal del lenguaje SAS es el paso DATA. Este elemento crea, modifica y transforma conjunto de datos SAS (datasets). El paso DATA se compone de 2 fases, la fase de compilación y la fase de ejecución. En la fase de compilación DATA crea una estructura de memoria, conocida como program data vector (PDV), con la estructura que SAS considera más adecuada para el conjunto de datos, paralelamente crea toda una descripción de la información del dataset. Una vez creada la estructura de la tabla SAS se pasa a la fase de ejecución en la que SAS itera con cada registro haciendo “output” en el dataset cuando SAS llega a la sentencia RUN. La iteración se lleva a cabo hasta que SAS detecta el final del archivo.

5.1 Leer ficheros de datos con SAS. Creación de datasets SAS puede interactuar con múltiples entornos de información, ahí reside su mayor potencia. Recordemos que SAS se compone de un módulo BASE al que se le añaden distintos módulos

Page 11: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

en función de las necesidades del entorno de información. En el presente manual se estudiarán las lecturas de ficheros de datos SAS manuales, de texto y de otros ficheros SAS.

5.1.1 Ficheros SAS de entrada manual

Anteriormente se estudió este programa: /*PROGRAMA 1*/ data uno; input x $ y; cards; 1 34 2 54 3 78 ; run; Esta es la entrada de datos que se considera manual. Para crear o sobrescribir un conjunto de datos SAS siempre emplearemos un paso DATA. Este paso crea un conjunto de datos SAS, en nuestro caso con INPUT le marcamos que la entrada va a ser manual, los datos los introducimos tras la sentencia CARDS. Todas las sentencias de SAS finalizan con ; y la ejecución de un paso DATA finaliza con la sentencia RUN; Imaginemos que tenemos la siguiente tabla: Paisano Estatura (cm) Peso (kg) Pepe 160 70 Juan 178 78 Alberto 200 120 Lucas 190 89 Una forma de introducir esta tabla en SAS sería: data tabla; input paisano $8. estatura_cm peso_cm; cards; Pepe 160 70 Juan 178 78 Alberto 200 120 Lucas 190 89 ; run; Si observamos la variable paisano va precedida de $8. es la forma en la que asignamos formatos a las variables en SAS, por defecto todas las variables SAS son numéricas necesitamos poner $ después de todas las variables alfanuméricas para indicarle lo contrario. Los formatos pueden ser de lectura (lo que introducimos a SAS) o pueden ser de escritura (lo que nos ofrece SAS). Los formatos más habituales son para variables alfanuméricas $charw. abreviado $w. y para variables numéricas w.[d] donde w es la longitud.

5.1.2 Lectura de ficheros de texto

Algo muy habitual en el trabajo diario con SAS es la lectura de ficheros de texto. El objetivo es transformar un fichero plano en un conjunto de datos SAS. Para realizar esta importación disponemos de un asistente: Menú archivo --> Importar datos

Page 12: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

La siguiente pantalla es:

En este punto podemos indicarle a SAS el formato del fichero de texto que deseamos importar. Habitualmente se emplean los ficheros estándar delimitado por comas (csv) o delimitado por tabuladores (txt). Sin embargo podemos indicarle a SAS cualquier tipo de archivo:

El siguiente paso es escribir la ubicación física en la que está el fichero:

El botón Options nos permite jugar con las opciones de importación del fichero:

Page 13: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

En este punto podemos indicar el delimitador y si el fichero de texto contiene encabezados. Aceptamos y el siguiente paso es indicar en el lugar en que queremos guardar la tabla SAS resultante:

Elegimos la librería y el nombre del conjunto de datos. Seguimos con el siguiente paso:

En este punto SAS nos indica si deseamos guardar el código resultante de la importación. No es necesario guardarlo puesto que posteriormente podemos recuperarlo. Pulsamos finalizar y ya habríamos importado correctamente el fichero de texto. El proceso no parece complicado pero, al igual que sucede con muchas herramientas de BBDD, en ocasiones la importación no se ha ejecutado correctamente porque un campo no se ha importado con el formato deseado o se ha provocado un error de importación y necesita de una intervención manual, necesita de programar el paso data que realiza la importación. En estos casos tras ejecutar la importación como antes lo indicamos podemos recuperar el último código ejecutado pulsando la tecla F4 en el editor de texto. SAS nos ha generado automáticamente el paso data de la importación, el código automático siempre tiene esta estructura:

Page 14: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

/********************************************************************** * PRODUCT: SAS * VERSION: 9.1 * CREATOR: External File Interface * DATE: 12NOV07 * DESC: Generated SAS Datastep Code * TEMPLATE SOURCE: (None Specified.) ***********************************************************************/ data WORK.PRUEBA ; %let _EFIERR_ = 0; /* set the ERROR detection macro variable */ infile 'C:\Datos\Datos.txt' delimiter='09'x MISSOVER DSD lrecl=32767 firstobs=2 ; informat ID best32. ; informat dato $1. ; format ID best12. ; format dato $1. ; input ID dato $ ; if _ERROR_ then call symput('_EFIERR_',1); /* set ERROR detection macro variable */ run; Esto es un código automático generado por SAS. En el que indicamos un fichero de entrada (infile) con un formato de entrada (informat) y que nos genera un conjunto de datos SAS. Para conocer mejor esta estructura es necesario conocer los distintos tipos de variables que tiene SAS.

5.1.3 Lectura de otros ficheros SAS

Lo más habitual en SAS es la lectura de otros conjuntos de datos para crear subconjuntos o nuevas variables. La sintaxis habitual para seleccionar datasets es: data prueba; input var1 var2 var3; cards; 100 20 30 300 45 60 700 34 67 500 34 12 900 90 45 ; run; data prueba2; set prueba; run; Con este programa asignamos al dataset prueba2 las mismas características del dataset prueba creado como ejemplo con anterioridad. La instrucción set lee las observaciones de uno o varios dataset que se indican a continuación. El paso data es el que genera o modifica los datasets que estemos empleando. Si deseamos crear una nueva variable dentro de un dataset la sintaxis sería: data prueba; set prueba; var_nueva=ranuni(5); run;

Page 15: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Este paso data nos crea en nuestro dataset una nueva variable var_nueva que es el resultado de la creación de un número aleatorio con la función de SAS ranuni(). Importante: la instrucción set debe ponerse si no queremos perder nuestro conjunto de datos. Dentro de un paso DATA también podemos seleccionar las variables que deben formar parte de él. Para esto contamos con las instrucciones KEEP y DROP. KEEP selecciona las variables que deseamos que formen parte de nuestro dataset, con DROP eliminamos las variables que no deseamos que aparezcan. La sintaxis para estas instrucciones es: data prueba; set prueba; keep ID var_nueva; var_nueva=ranuni(5); run;

Con la instrucción KEEP nos quedamos con las variables ID var_nueva en el dataset prueba. La instrucción DROP elimina las variables: data prueba; set prueba; drop dato; var_nueva=ranuni(5); run; Para crear subconjuntos de datos a partir de un dataset emplearemos sentencias condicionales y lógicas. El bloque IF/THEN/ELSE nos permite ejecutar sentencias en modo condicional, la sintaxis de este bloque es: IF (si) <condición> THEN (entonces) <acción1>; ELSE <acción2>; Si, por ejemplo, quisiéramos crear una nueva variable que me identificara que valores de var_nueva tienen un valor superior a 0.5 la sintaxis necesaria sería: data prueba; set prueba; if var_nueva>0.5 then var_condicional="mayor 0.5"; else var_condicional="menor 0.5"; run; Con este paso data hemos creado una variable llamada var_condicional de tipo alfanumérico que toma dos valores en función del valor de var_nueva. En un mismo paso data podemos crear varios datasets. Siguiendo con el ejemplo dividamos prueba en dos subconjuntos de datos: data prueba_mas_05 prueba_menos_05; set prueba; if var_nueva>0.5 then output prueba_mas_05; else output prueba_menos_05; run; En este caso prueba genera dos subconjuntos de datos en función del valor de una variable. Para indicarle a SAS en que momento debe efectuar la copia de la información en cada subconjunto empleamos la instrucción OUTPUT. Las sentencias condicionales se pueden anidar: IF (si) <condición> THEN (entonces) <acción1>; ELSE IF (si) <condición> THEN (entonces) <acción2>; ELSE IF (si) <condición> THEN (entonces) <acción3>;

Page 16: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

··· ELSE IF (si) <condición> THEN (entonces) <acciónN>; ELSE <accionN+1>; En el ejemplo de la creación de varios subconjuntos de datos podemos hacer: data prueba_menos_02 prueba_02_05 prueba_mas_05; set prueba; if var_nueva<0.2 then output prueba_menos_02; else if var_nueva<0.5 then output prueba_02_05; else output prueba_mas_05; run; Otra labor de gran utilidad será la realización de múltiples acciones en un bloque condicional, para ello tendremos que crear bloques de acciones: IF (si) <condición> THEN (entonces) DO (abre bloque de acciones); Accion1; Accion2; ... AccionN; END (cierra bloque de acciones); ELSE <acción2>; Veamos el funcionamiento del bloque de acciones con un ejemplo: data prueba; set prueba; if var_nueva>0.5 then do; var_condicional1="mayor 0.5"; var_condicional2="> 0.5"; end; else do; var_condicional="menor 0.5"; var_condicional2="< 0.5"; end; run; Evidentemente podemos combinar bloques de acciones con condiciones anidadas. Las sentencias IF también pueden ejercer como filtros de selección, es este caso no necesitarían ir acompañadas de THEN/ELSE: data prueba_mas_05; set prueba; if var_nueva>0.5 ; run; En este ejemplo sólo seleccionaríamos las observaciones con un valor para var_nueva por encima de 0.5. En este caso IF equivale a una sentencia de selección con un determinado criterio. Otra instrucción que realiza sentencias de selección es WHERE <condición1> ... <condiciónN>. De este modo el ejemplo anterior se podría escribir: data prueba_mas_05; set prueba; where var_nueva>0.5 ; run; En esta circunstancia IF equivale a WHERE ya que no realiza acción alguna, si no un filtrado de las observaciones, un subconjunto de datos SAS.

Page 17: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

5.2 Variables El elemento fundamental de los conjuntos de datos SAS son las variables. Ya las hemos referenciado en capítulos anteriores. Éstas pueden ser numéricas o alfanuméricas. Las variables se pueden crear, eliminar (recordemos la instrucción DROP) o se pueden recodificar. Todo esto siempre lo haremos mediante pasos DATA. Disponemos de un amplio número de funciones para que todas las variables se ajusten a nuestras necesidades. Cada variable tiene una serie de atributos que podemos modificar:

Atributo Definición SAS Valores

Nombre Name Ver reglas SAS Tipo Type num, char Longitud Length 2 - 8 bytes para num, 1 - 32,000 para char Formato salida Format Por defecto para num BEST12. , $w. Para char Formato de entrada Informat Por defecto para num BEST12. , $w. Para char Etiqueta Label Ninguna Un tipo muy especial de variable es el valor perdido o missing. Por defecto el missing para una variable numérica es . y ‘ ‘ para una variable alfanumérica. Para todas las variables podemos emplear operadores de comparación (por ejemplo en sentencias IF) y/o operadores lógicos. Los operadores de comparación son: Símbolo Equivalencia Ejemplo = EQ a=3 ^= NE a ne 3 ¬= NE ~= NE > GT num>5 < LT num<8 >= GE sales>=300 <= LE sales<=100 IN num in (3, 4, 5) Los operadores lógicos son: Símbolo Equivalencia Ejemplo & AND (a>b & c>d) | OR (a>b or c>d) ! OR ¦ OR ¬ NOT not(a>b) ˆ NOT ~ NOT

5.2.1 Variables numéricas

Son las variables que representan números, son medidas de cada observación de nuestro dataset. Dentro de las numéricas se incluyen las variables de fecha y hora. Su longitud va desde los 2 a los 8 bytes. El formato que tienen por defecto es BEST12. que es el formato de 12 bytes que SAS considera más adecuado para una variable numérica. La forma más

Page 18: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

común de representar las variables numéricas es w.[d] donde w representa la longitud de la parte entera y d la longitud de la parte decimal. Los operadores matemáticos fundamentales que se pueden emplear con las variables numéricas son: Operador Definición Ejemplo ** Exponecial a**3

* Multiplicar 2*y

/ Dividir var/5

+ Sumar num+3

- Restar sale-discount

Los missing numéricos tienen un comportamiento especial y debemos tener especial cuidado al trabajar con variables numéricas que puedan contener valores perdidos. Analicemos algunos ejemplos: data _null_; y=3; x=.; z=x+y; l=x*y; m=min(x,y); n=sum(x,y); put z= l= m= n=; run; La sentencia DATA _NULL_ no genera conjunto de datos SAS, _NULL_ es un tipo especial de dataset que no genera un fichero físico; con la instrucción PUT= nuestro paso data escribirá en la ventana log el valor de las variables que deseamos ver. Si analizamos el resultado en la ventana log tendremos:

Una variable missing que opera con un número da como resultado una variable missing, sin embargo si empleamos una función de SAS como es min() para determinar el mínimo entre dos valores o sum() para determinar la suma el valor missing no es tenido en cuenta.

Page 19: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

5.2.2 Variables fecha

Un tipo muy importante de variable numérica es la variable que representa una fecha u hora en SAS. La variable fecha se codifica internamente como la diferencia en días entre la fecha en cuestión y el 1 de enero de 1960 de modo que las fechas posteriores serán un número positivo y las anteriores a 1960 serán un número negativo. Igualmente las variables hora serán la diferencia en horas con el 1 de enero de 1960 a las 00:00. Analicemos con algunos ejemplos como codifica SAS las variables fecha: data fechas; input id $5. fecha : ddmmyy10.; cards; AAAAA 01/01/1960 ABAAC 01/01/1961 ACBAC 01/01/1970 ACABA 01/01/1962 AAAAC 01/01/1980 ; run; Este programa crea desde el editor un conjunto de datos SAS con una variable carácter y otra numérica a la que a través de : ddmmyy10. le asignamos un formato de lectura a SAS. Si hacemos una vista del conjunto de datos tenemos:

Vemos como se codifican las variables fecha como la diferencia en días respecto el 01/01/1960. Si deseamos ver el valor fecha que toma esta variable deberemos asignarle un formato de salida. Esto lo podemos hacer desde el mismo paso data: data fechas; input id $5. fecha : ddmmyy10.; format fecha ddmmyy10.; cards; AAAAA 01/01/1960 ABAAC 01/01/1961 ACBAC 01/01/1970 ACABA 01/01/1962 AAAAC 01/01/1980 ; run;

El formato es uno de los atributos más importantes de las variables y en función de él podremos ver correctamente los resultados. Los formatos fecha/hora más empleados son: Formato Longitud

máxima Longitud mínima

Longitud por defecto

Page 20: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

DATE. 5 9 7 DATETIME. 7 40 16 DDMMYY. 2 10 8 Para operar con variables fecha podemos emplear los mismos operadores que hemos visto para las variables numéricas pero cabe destacar que SAS dispone de numerosas funciones para el trabajo con variables de este tipo. Las funciones más destacadas son:

DATDIF Function Días entre 2 fechas

DATE Function Fecha de inicio de sesión de SAS

DATEPART Function Extrae fecha SAS de una variable fecha/hora

DAY Function Día de la fecha SAS

HMS Function Hora, minutos y segundos de variable fecha/hora

HOUR Function Hora de fecha INTCK Function Intervalo de tiempo entre 2 fechas MDY Function Crea fechas SAS introduciendo mes día y año

MINUTE Function Minuto de fecha

MONTH Function Mes de fecha

SECOND Function Segundo de fecha

TIME Function Hora actual del sistema

TIMEPART Function Extrae tiempo de fecha/hora

TODAY Function Día actual a fecha SAS

WEEKDAY Function Día de la semana de fecha

YEAR Function Año de fecha Para introducir en un paso DATA una constante fecha, realizar operaciones con fechas por ejemplo, hemos de hacerlo en formato DATE. Veamos un ejemplo: data fechas; input id $5. fecha : ddmmyy10.; format fecha ddmmyy10.; cards; AAAAA 01/01/1960 ABAAC 01/01/1961 ACBAC 01/01/1970 ACABA 01/01/1962 AAAAC 01/01/1980 ; run; data fechas; set fechas; anyos_entre_dos_fechas= ("01NOV80"d - fecha)/365.25; run; Las constantes fecha han de introducirse con “DIA(MES EN INGLES)AÑO”d, también pueden introducirse como el valor numérico de la fecha, pero parece más práctica esta metodología.

5.2.3 Variables alfanuméricas

Las variables alfanuméricas son aquellas que almacenan caracteres. Su longitud puede ir de 1 a 32.000 bytes. En anteriores ejemplos ya hemos visto la forma de introducir manualmente variables carácter a través de INPUT, sin embargo si queremos realizar modificaciones sobre ellas, crear nuevas variables o trabajar con constantes tendremos que emplear las comillas (simples ‘ o dobles ”). Por ejemplo, retomando la tabla fechas creada anteriormente tenemos: data fechas;

Page 21: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

input id $5. fecha : ddmmyy10.; format fecha ddmmyy10.; cards; AAAAA 01/01/1960 ABAAC 01/01/1961 ACBAC 01/01/1970 ACABA 01/01/1962 AAAAC 01/01/1980 ; Sobre esta tabla se nos solicita añadir al campo id el prefijo ID-. El programa SAS que se emplea para modificar este campo sería: data fechas; set fechas; id="ID-"||id; run; El operador fundamental para las variables alfanuméricas es la concatenación, para ello SAS emplea ||. Para trabajar con constantes de caracteres es necesario el uso de comillas. De este modo modificamos nuestro campo id añadiéndole un prefijo. Veamos la tabla resultante:

Como vemos el resultado no es el correcto debido a que nuestra variable se ha recalculado sobre ella misma y, en principio, le asignamos un tamaño de $5 (ver input). Para conocer las características de las variables de un dataset podemos emplear el explorador de librerías. Si nos situamos sobre el explorador y pulsamos el botón derecho podemos realizar diversas acciones sobre un dataset:

En nuestro caso nos interesa ver las columnas para conocer su estructura, pero si empleamos el botón Propiedades:

Page 22: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Esta ventana recoge todo lo que compone un dataset. Las pestañas fundamentales son General y Columnas. En General podemos ver el tamaño y las fechas de modificación, en columnas la información nos será de gran utilidad para trabajar con variables:

Nuestro dataset ejemplo se compone de 2 variables, una de texto de longitud 5 y otra numérica de longitud 8 con formato de salida DDMMYY10. Para modificar los atributos de nuestro dataset y que nuestra variable tenga la forma que deseamos hemos de emplear la instrucción ATTRIB pero con una peculiaridad, lo vemos en el ejemplo: data fechas; attrib id length=$10; set fechas; id="ID-"||id; run;

Page 23: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

La instrucción ATTRIB modifica los atributos de nuestras variables, los posibles atributos a modificar son: LENGTH, LABEL, FORMAT e INFORMAT. Siempre ha de ir antes de poner SET para poder asignar unos atributos iniciales. SAS dispone de un gran número de funciones para el tratamiento de variables carácter, de todas ellas destacan: Función Descripción COMPRESS Elimina un carácter específico COUNT Cuenta el número de veces que aparece un carácter INDEX Busca una cadena de caracteres LEFT Alinea a la izquierda LENGTH Obtiene la longitud de una variable carácter LOWCASE Pone en minúsculas MISSING Indica si la variable es missing QUOTE Pone comillas REVERSE Reversa de carácter RIGHT Alinea a la derecha SCAN Busca una cadena de caracteres dentro de otra cadena SUBSTR Extrae partes de una cadena TRANWRD Reemplaza o extrae dentro de una cadena TRIMN Elimina espacios en blanco innecesarios UPCASE Pone en mayúsculas

5.2.4 Formatos de variables

En capítulos anteriores ya se ha hecho mención a los formatos de las variables. Son imprescindibles tanto para leer como para escribir variables. Y esa es la característica que los divide, existen formatos de entrada INFORMAT y formatos de salida FORMAT. Se dividen por categorías, entre las que destacan los formatos numéricos, formatos carácter y formatos de fecha. Para entender mejor la sintaxis SAS que genera formatos recordamos uno de los ejemplos vistos en el presente manual: data WORK.PRUEBA ; %let _EFIERR_ = 0; /* set the ERROR detection macro variable */ infile 'C:\Datos\Datos.txt' delimiter='09'x MISSOVER DSD lrecl=32767 firstobs=2 ; informat ID best32. ; informat dato $1. ; format ID best12. ; format dato $1. ; input ID dato $ ; if _ERROR_ then call symput('_EFIERR_',1); /* set ERROR detection macro variable */ run; Este es el código SAS que se genera automáticamente tras la “rellamada”, tras el RECALL de la importación de un conjunto de datos de texto. Analizando las sentencias que asignan formatos tenemos:

Page 24: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

informat ID best32. ; informat dato $1. ; format ID best12. ; format dato $1. ; INFORMAT indica al sistema que la variable de lectura es numérica formato BEST12. para dato tenemos un formato de lectura carácter de longitud 1. Los formatos de salida, en la sentencia FORMAT son los mismos. Así pues la sintaxis es sencilla (IN)FORMAT <variable/s> <formato>; Los formatos más importantes por tipo son: Formatos numéricos: Formato Descripción BESTw. SAS mejor formato BINARYw. Binario COMMAw.d Separación de miles y decimales en formato americano COMMAXw.d Separación de miles y decimales en formato europeo EUROw.d Formato euro con configuración americana EUROXw.d Formato euro con configuración europea FRACTw. Número fraccionario HEXw. Hexadecimal ROMANw. Romano w.d Habitual de <parte entera>.<parte decimal> Zw.d Números empezados por 0 En el caso de las variables numéricas el formato de lectura y escritura será sólo relevante para los reportes más sofisticados. Formatos fecha (vistos con anterioridad): Formato Descripción DATE. Día siglas de mes en inglés Año DATETIME. Como date pero con HH:MM:SS DDMMYY. DD/MM/YY En el caso de las fechas es fundamental conocer bien el funcionamiento de los formatos tanto de lectura, para la importación de ficheros de texto; como de escritura, para la realización de cálculos y reportes. Formatos carácter: Formato Descripción $CHARw. $w.

Carácter estándar

Como podemos ver para los formatos carácter sólo destaca el formato estándar. Cuando trabajemos con variables carácter la información que requerirá más atención será su longitud.

5.2.5 Variables dentro del paso DATA

El lugar donde operamos con variables es el paso DATA. Dentro de un dataset las operaciones más habituales con variables son:

• Selección de variables • Renombramiento de variables • Ordenación de variables dentro de un conjunto de datos SAS • Recodificación y cálculo de variables

Page 25: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Selección de variables: En el capítulo 5.3.1 ya se hizo referencia a las instrucciones KEEP y DROP. KEEP selecciona las variables en el conjunto de datos SAS y DROP las elimina. Estas instrucciones se pueden emplear en sentencias o como opción del paso data. Renombramiento de variables: Para modificar el nombre de una variable se emplea la instrucción RENAME. Al igual que KEEP y DROP puede ser sentencia u opción de un paso DATA. Ordenación de variables: Para ordenar variables dentro de un conjunto de datos SAS emplearemos la instrucción RETAIN siempre antes de la sentencia que incluya SET. Recodificación y cálculo de variables: Para la manipulación y transformación de variables emplearemos las numerosas funciones que dispone SAS. Para familiarizarnos con las distintas operaciones que podemos hacer con variables en un paso DATA emplearemos un ejemplo: data ejemplo; do indice=1 to 20; Numero_alumno=int(ranuni(8)*10000); Estatura=rannor(3)*15+175; Peso=rannor(3)*10+80; Nota1=ranpoi(34,5); Nota2=ranpoi(34,5); Nota3=ranpoi(34,5); output; end; run; El dataset ejemplo tiene 20 observaciones creadas con un bucle DO. Tiene 7 variables, un índice empleado para el bucle y 6 variables aleatorias que simulan un grupo de alumnos con su identificador, su estatura, su peso y sus notas en determinadas asignaturas. El bucle DO itera tantas veces como le indiquemos con los índices (siempre separados por TO), con OUTPUT le indicamos a SAS que tras cada iteración vuelque los datos al dataset. Para comenzar a conocer mejor el manejo de variables mediante un paso DATA en primera instancia crearemos un nuevo conjunto de datos SAS llamado ejemplo2 que contendrá las variables Numero_alumno y Nota: /*1*/ data ejemplo2; set ejemplo; keep numero_alumno nota1 nota2 nota3; run; /*2*/ data ejemplo2; set ejemplo; drop indice estatura peso; run; /*3*/ data ejemplo2; set ejemplo (keep=numero_alumno nota1 nota2 nota3); run; /*4*/ data ejemplo2; set ejemplo (drop=indice estatura peso); run; Estos 4 programas hacen exactamente lo mismo, podemos seleccionar o eliminar variables obteniendo el mismo resultado. Como novedad tenemos DROP y KEEP como opciones

Page 26: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

dentro de una sentencia SET, en este caso la sintaxis requiere estar entre paréntesis y un igual después de DROP o KEEP, esta será la forma en la que trabajaremos con las opciones de lectura/escritura dentro de las sentencias SET/DATA. Como siguiente ejemplo vamos a necesitar realizar una modificación en el dataset ejemplo2, renombrar la variable numero_alumno como id_alumno y nota1 como nota5, además necesitamos una nueva variable llamada clase que tenga el valor 1ºA (será una constante), el código SAS sería: /*1*/ data ejemplo2; set ejemplo2; clase="1ºA"; rename numero_alumno = id_alumno Nota1 = Nota5; run; /*2*/ data ejemplo2 (rename=(numero_alumno = id_alumno Nota1 = Nota5)); set ejemplo2; clase="1ºA"; run; Para este ejemplo presentamos 2 posibles formas de hacerlo, bien empleando RENAME como una instrucción dentro del paso DATA o como opción de escritura (va en la sentencia DATA) del dataset que creamos. De este modo tanto RENAME como KEEP/DROP pueden ser sentencias del paso DATA u opciones de lectura/escritura: /*OPCIONES DE ESCRITURA: EN SENTENCIA DATA*/ data dataset_escritura (drop=variables keep=variables rename=nombre1=nuevo_nombre2 ... ); /*OPCIONES DE LECTURA: EN SENTENCIA SET*/ set dataset_lectura (drop=variables keep=variables rename=nombre1=nuevo_nombre2 ... ); /*INSTRUCCIONES*/ run; Importante: si empleamos las opciones de lectura (en SET) modificaremos la estructura el dataset leído. Los resultados obtenidos con las opciones lectura/escritura de un dataset son análogas a las que podríamos obtener con: data dataset_escritura ; set dataset_lectura; /*SENTENCIAS RENAME KEEP/DROP*/ rename nombre1=nuevo_nombre2 ... nombren=nuevo_nombren; keep variables; drop variables; run; Trabajar con sentencias específicas o con opciones de lectura/escritura del dataset dependerá de la tarea que deseemos realizar. Las opciones de lectura/escritura optimizan el uso de memoria pero modifican la estructura de un dataset. Las sentencias específicas RENAME, KEEP o DROP penalizan el uso de la memoria pero nos garantizan que se mantiene la estructura del dataset leído y la estructura del dataset a escribir.

Page 27: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Continuando con nuestro ejemplo práctico deseamos retocar el orden de las variables a la vez que renombramos dos de las variables. Para ello debemos emplear una sentencia con la instrucción RETAIN: data ejemplo2; retain clase id_alumno Nota2 Nota3 Nota5; set ejemplo2; clase="1ºA"; rename numero_alumno = id_alumno Nota1 = Nota5; run; Observemos que en RETAIN debemos poner el nombre “antiguo” de la variable porque estamos modificando la estructura en el momento de la compilación del paso DATA. Avanzando en nuestro ejemplo vamos a crear un nuevo dataset con un identificador de alumno resultado de la concatenación de clase e id; además será necesario el cálculo de la nota media de las 3 asignaturas, recodificamos y modificamos dos variables: data ejemplo3; retain new_id_alumno; set ejemplo2; drop clase id_alumno; new_id_alumno=compress(clase||"-"||id_alumno); nota_media=mean(nota2,nota3,nota5); format nota_media 5.2; run; En este ejemplo creamos dos nuevas variables: new_id_alumno nota_media. La primera es la concatenación de una variable carácter con un guión y una variable numérica, esta concatenación está dentro de la función COMPRESS que se emplea habitualmente para eliminar espacios en blanco dentro de una variable carácter. Para la nota media se ha empleado la función estadística MEAN, a la variable generada se le asigna un formato de longitud 5 con 2 posiciones decimales.

5.3 Observaciones Hasta el momento hemos creado conjuntos de datos SAS y hemos trabajado con las variables que lo componen. El otro elemento que requiere de estudio por parte de este manual es la fila de una tabla, las observaciones de un dataset. Las observaciones son añadidas al dataset en el momento del “output”. Por defecto el momento de output será la sentencia RUN, sin embargo podemos indicar ese momento dentro de un paso DATA precisamente con la instrucción OUTPUT, veamos un ejemplo de funcionamiento: data ejemplo; do indice=1 to 20; Numero_alumno=int(ranuni(8)*10000); Estatura=rannor(3)*15+175; Peso=rannor(3)*10+80; Nota1=ranpoi(34,5); Nota2=ranpoi(34,5); Nota3=ranpoi(34,5); output; end; run; data ejemplo_par ejemplo_impar; set ejemplo; if mod(indice,2)=0 then output ejemplo_par; else output ejemplo_impar; run;

Page 28: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Si analizamos estos ejemplos tenemos que ejemplo se crea mediante un bucle DO en el que al final se ejecuta OUTPUT, el final del bucle será el momento en el que SAS realiza la salida de al conjunto de datos. En el siguiente paso data vemos que la instrucción DATA va a generar 2 conjuntos de datos SAS. El paso data puede generar de 0 a n conjunto de datos SAS, si deseamos hacer un paso data sin generar dataset emplearemos data _null_; En este caso generamos ejemplo_par y ejemplo_impar, ambos parten de ejemplo y en el caso de que el índice sea par entonces se realiza un output sobre ejemplo_par y en el caso contrario se realiza el output sobre ejemplo_impar. Con OUTPUT podemos controlar aquellas observaciones que queremos que se carguen en nuestro dataset, si deseamos el efecto contrario, la eliminación de observaciones, deberemos emplear la instrucción DELETE. El siguiente programa elimina del dataset ejemplo aquellas observaciones con una nota media inferior a 5: data ejemplo_aprobados; set ejemplo; if mean(nota1,nota2,nota3) < 5 then delete; run; Otra forma de controlar las observaciones que deseamos en nuestro dataset es el filtrado de registros, para ello emplearemos la instrucción WHERE <condición> vista con anterioridad: data aprobados; set ejemplo; where nota1 >= 5 and nota2 >= 5 and nota3 >=5; run; WHERE es una instrucción que puede ser también opción de lectura o escritura dentro del paso DATA, al igual que SEP/DROP y RENAME. Como opción nos será de gran utilidad para optimizar el proceso de lectura de datasets: data aprobados; set ejemplo (where=( nota1 >= 5 and nota2 >= 5 and nota3 >=5)); run; En este punto disponemos de herramientas de código que nos permiten controlar el momento en el que una observación pasa a formar parte, o no, de nuestro conjunto de datos. Un caso particular de trabajo con observaciones será la agrupación de ellas por una variable agrupadora, analicemos un ejemplo práctico: Disponemos de las ciudades con más de 100.000 habitantes de las provincias de Madrid y Barcelona:

Provincia Municipio Cod_postal Población

Madrid Madrid 28079 3092759 Barcelona Barcelona 8019 1582738 Barcelona Hospitalet de Llobregat (L') 8101 246415 Barcelona Sabadell 8187 191057 Madrid Alcorcón 28007 154441 Madrid Móstoles 28092 201789 Barcelona Terrassa 8279 184829 Madrid Getafe 28065 156315 Madrid Leganés 28074 176900 Madrid Fuenlabrada 28058 187963 Madrid Alcalá de Henares 28005 188519 Barcelona Badalona 8015 214440 Madrid Torrejón de Ardoz 28148 104790 Barcelona Mataró 8121 111879

Page 29: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Barcelona Santa Coloma de Gramenet 8245 116012

Para estas provincias necesitamos un total de habitantes. Es decir, necesitamos una variable que nos sume la población por provincia. El primer paso es introducir los datos en SAS: data datos; input Provincia $10.Municipio $30. Cod_postal Poblacion ; format cod_postal z5.; cards; Madrid Madrid 28079 3092759 Barcelona Barcelona 8019 1582738 Barcelona Hospitalet de Llobregat (L') 8101 246415 Barcelona Sabadell 8187 191057 Madrid Alcorcón 28007 154441 Madrid Móstoles 28092 201789 Barcelona Terrassa 8279 184829 Madrid Getafe 28065 156315 Madrid Leganés 28074 176900 Madrid Fuenlabrada 28058 187963 Madrid Alcalá de Henares 28005 188519 Barcelona Badalona 8015 214440 Madrid Torrejón de Ardoz 28148 104790 Barcelona Mataró 8121 111879 Barcelona Santa Coloma de Gramenet 8245 116012 ; run; Introducimos manualmente los datos, cabe destacar que a cod_postal le damos un formato de salida z5. que rellena con 0 a la izquierda en 5 posiciones. Para agrupar por una variable en un paso DATA necesitamos que el conjunto de datos esté previamente ordenado por esa variable. La ordenación de datasets se lleva a cabo con el procedimiento SORT cuya sintaxis es: PROC SORT DATA=<datos> <opciones>; BY (DESCENDING) <variable>; RUN; En el ejemplo que nos ocupa el procedimiento SORT queda: proc sort data=datos; by provincia; /*VARIABLE POR LA CUAL SE ORDENA*/ run; Vemos que la sintaxis de este procedimiento es muy sencilla. Ahora nuestro dataset está ordenado por la variable provincia, pasamos a crear la variable agregada. Para este fin hemos de emplear la instrucción RETAIN vista con anterioridad cuando ordenábamos variables dentro de nuestro dataset. En este caso RETAIN retendrá el valor de una variable tras cada iteración del paso data y no la posición de las variables dentro de una tabla como hacía con anterioridad. Para agrupar hemos de trabajar con unas variables de sistema específicas para el trabajo con agregados. Estas variables son creadas en el sistema por la instrucción BY. Como hemos visto en el procedimiento SORT la instrucción BY nos ha indicado la variable por la cual ordenamos el dataset, pues bien, en el paso DATA nos indicará lo mismo: la variable que ordena el dataset. Es imprescindible para el uso de BY que el dataset esté ordenado, en el caso contrario obtendremos un error. Veamos la sintaxis de la agrupación: data datos_agregados; set datos; /*VARIABLE DE RETENCION*/ retain total_poblacion 0; /*VARIABLE PARA AGRUPAR*/

Page 30: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

by provincia; /*TRABAJO CON VARIABLES DE SISTEMA*/ /*VARIABLE FIRST*/ if first.provincia then total_poblacion=0; total_poblacion=sum(total_poblacion,poblacion); /*VARIABLE LAST*/ if last.provincia then output; keep provincia total_poblacion; run; Vemos que RETAIN nos crea una nueva variable en nuestro dataset con formato numérico y cuyo valor inicial será 0, esta variable será la que retenga su valor tras cada iteración de datos. Al emplear BY SAS nos permite trabajar con dos variables internas del paso data (no tendrán output) FIRST.<variable en BY> y LAST. .<variable en BY>. FIRST. toma el valor 1 cuando estamos ante la primera observación del grupo de la variable de BY y 0 en el resto de posiciones de la variable y LAST. toma el valor 1 cuando estamos ante la última observación del grupo. En el ejemplo antes analizado, realizando unas modificaciones podemos ver que valores toman FIRST. y LAST. en función de la variable agrupadora: data valores_BY; set datos; /*VARIABLE PARA AGRUPAR*/ by provincia; valor_first=first.provincia; valor_last=last.provincia; run; Podemos realizar agrupaciones por más de una variable. Si en el ejemplo en estudio deseamos crear una nueva variable “ranking” por el número de habitantes la metodología a emplear sería la siguiente: proc sort data=datos; by provincia descending poblacion; run; data datos_ranking; set datos; retain ranking 0; by provincia;

Primer valor para variable grupo: Barcelona

Último valor para variable grupo: Barcelona

Variable grupo, indicada con BY

Page 31: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

if first.provincia then ranking = 1; else ranking=ranking + 1; run;

6. Uniones de conjuntos de datos SAS

6.1 Tipos de uniones Para unir conjuntos de datos SAS será necesario tener en cuenta el tipo de unión que deseamos realizar. Dos son los tipos fundamentales:

• Unión vertical: o Concatenación:

o Intercalación:

• Unión horizontal:

DATA A DATA B Concatenación A y B

2000 2005 20002001 2006 20012002 2007 20022003 2008 20032004 2004

2005200620072008

DATA A DATA B Intercalcación A y B

2000 2001 20002001 2003 20012002 2007 20012003 2008 20022004 2003

2003200420072008

Page 32: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Estas son las 3 formas más habituales de unir conjuntos de datos SAS. En el primer caso, la concatenación de datasets, emplearemos la instrucción SET. Al igual que se emplea para leer las observaciones de una tabla dentro de un paso data se puede emplear para leer más de una tabla. Veamos un ejemplo: data uno; input anio ; cards; 2000 2001 2002 2003 2004 ; run; data dos; input anio ; cards; 2005 2006 2007 ; run; data tres; set uno dos; run; proc print data=tres; run; Creamos dos conjuntos de datos ambos con la misma y única variable. Los unimos en el conjunto de datos tres, c el procedimiento PRINT imprimimos en la ventana output el contenido del dataset:

Se observa que el resultado final es la unión de las dos tablas uno y dos. El resultado final tiene 8 observaciones 5 de uno y 3 de dos. Para intercalar datasets también emplearemos la instrucción SET pero será necesario que le indiquemos a SAS mediante que variable realizamos la intercalación, esto lo haremos con la instrucción BY. Por ello, para intercalar

DATA A DATA B Unión horizontal A y B

Año X Año Y Año X Y2000 99,60 2001 4 2000 99,60 .2001 30,35 2003 2 2001 30,35 42002 2,32 2007 18 2002 2,32 .2003 16,27 2008 19 2003 16,27 22004 35,82 2004 35,82 .

2007 . 182008 . 19

Page 33: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

datasets, necesitaremos que estén ordenados por la variable de intercalación, por la variable que participe en la sentencia creada con BY. Analicemos el correspondiente ejemplo de sintaxis: data uno; input anio importe; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; data tres; set uno dos; by anio; run; proc print data=tres; run;

Para realizar la intercalación entre conjuntos de datos SAS el paso previo siempre será la ordenación de los mismos, posteriormente los uniremos en un paso data seguido de una sentencia SET donde indicamos los conjuntos origen y por último emplearemos la sentencia BY que indica la variable mediante la cual realizamos la intercalación. El resultado final es un conjunto de datos que tiene 10 observaciones 5 de uno y 5 de dos donde la variable anio hace de “campo índice”. Para la unión horizontal la metodología será muy similar a la empleada en la intercalación, pero en este caso emplearemos la sentencia MERGE. El ejemplo a plantear es el siguiente: data uno; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos;

Page 34: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

input anio importe2; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; data tres; merge uno dos; by anio; run; proc print data=tres; run; El código es completamente análogo al empleado en la intercalación, ambos datasets han de estar ordenados y la posterior unión se lleva a cabo en un paso data que para leer las observaciones emplea la instrucción MERGE en vez del habitual SET. Las dos tablas tienen un campo común anio y un campo distinto que hace referencia a un importe. Nuestro objetivo es la unión de ambas tablas para crear un tercer conjunto de datos que contenga la unión horizontal de ambas tablas. El resultado en la ventana output es:

Tenemos 7 observaciones 5 de uno y 5 de dos pero en este caso 3 de las observaciones son coincidentes para ambas tablas, 2 observaciones de uno que no se encuentran en dos y 2 observaciones de dos que no se encuentran en uno.

6.2 Uniones habituales de tablas Hemos planteado la metodología para unir tablas SAS a través de un paso data pero en nuestro trabajo habitual existen otros tipos de uniones como búsqueda de coincidentes, intersección de tablas o añadir variables a un dataset provenientes de otro. La metodología será la empleada en la unión horizontal por lo que debemos tener las tablas que manejemos ordenadas por la variable que empleemos par el cruce. Emplearemos una variable de sistema que se genera en el paso data como opción de lectura en las sentencias MERGE o SET. Como norma general las opciones de lectura de un dataset irán entre paréntesis. En este caso la opción empleada será IN=<variable de sistema>. Las uniones más habituales serán:

6.2.1 Añadir nuevas variables a un conjunto de datos SAS

Page 35: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

El dataset A tiene una estructura a la que es necesaria unir alguna/s variables del dataset B, pero sólo en aquellos casos en los que cruce la observación de A, no podemos añadir observaciones de B. Retomando el ejemplo anterior de unión horizontal de datasets ahora pretendemos añadir al dataset uno las variables del dataset dos: data uno; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe2; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; data uno; merge uno (in=en_uno) dos; by anio; /*IN GENERA UNA VARIABLE DE SISTEMA LLAMADA EN_UNO QUE TOMARA EL VALOR 1 SI LA OBSERVACION ESTA EN EL DATASET INDICADO*/ if en_uno; run; proc print data=uno; run; La opción de lectura de uno (in=en_uno) genera una variable interna (no se realizará output de ella) que toma el valor 1 si la observación está en el dataset uno. De este modo tendremos como resultado todas las observaciones de uno a las que habremos añadido las variables de dos que tengan coincidencia en el campo de cruce indicado en BY:

Page 36: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Las 5 observaciones de uno tienen una variable más provenientes de dos. Importante: en este tipo de uniones prevalece la información que “añadimos por la derecha”: data uno; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe1; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; data uno; merge uno (in=en_uno) dos; by anio; /*IN GENERA UNA VARIABLE DE SISTEMA LLAMADA EN_UNO QUE TOMARA EL VALOR 1 SI LA OBSERVACION ESTA EN EL DATASET INDICADO*/ if en_uno; run; proc print data=uno; run;

Este tipo de cruce nos será de especial interés cuando necesitemos hacer actualizaciones de variables de nuestra tabla.

6.2.2 Búsqueda de observaciones coincidentes

Buscamos aquellas observaciones que están dentro de un dataset y no están dentro de otro:

La sintaxis de SAS sería:

Page 37: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

data uno; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe2; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; data uno; merge uno (in=en_uno) dos (in=en_dos keep=anio) /*DROP COMO OPCION DE LECTURA*/; by anio; if en_uno and not en_dos; run; proc print data=uno; run; En este caso no realizamos uniones de variables porque usamos KEEP como opción de lectura dentro de la sentencia MERGE, el dataset uno contendrá aquellas observaciones de uno que no coinciden con las observaciones de dos:

Si deseamos las observaciones coincidentes estaríamos ante una intersección de dos conjuntos de datos:

data uno; merge uno (in=en_uno) dos (in=en_dos keep=anio) /*DROP COMO OPCION DE LECTURA*/; by anio;

Page 38: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

if en_uno and en_dos; run; Importante: Estamos ante búsqueda de observaciones, MERGE siempre hará unión de las variables de los datasets que pongamos en su sentencia. Habrá ocasiones en las que necesitemos las variables y ocasiones en las que no necesitemos las variables, pero podemos añadir información que no es relevante a nuestro conjunto de datos e incluso sobrescribir variables. Cabe señalar que tanto usando SET como MERGE podemos unir de 2 a n conjuntos de datos, por ejemplo: data uno; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe2; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; data tres; input anio importe3; cards; 2003 4 2002 1 2000 2 2001 7 2006 6 ; run; proc sort data=uno; by anio; run; proc sort data=dos; by anio; run; proc sort data=tres; by anio; run; data uno; merge uno (in=en_uno) dos tres; by anio; if en_uno; run; proc print data=uno; run;

Page 39: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

7. Procedimientos básicos de SAS Hasta el momento hemos trabajado fundamentalmente con el paso DATA. El otro componente fundamental de un programa SAS el procedimiento, el paso PROC. Ya hemos esbozado dos de los procedimientos más habituales, SORT y PRINT. Aparte de estos dos se van a estudiar determinados procedimientos almacenados en el módulo BASE que pueden ser de especial interés:

• Summary/means • Freq • Datasets • Import/export • Univariate

7.1 PROC SORT El procedimiento SORT es el que emplearemos para la ordenación de conjuntos de datos. La sintaxis será: PROC SORT DATA=<dataset de lectura> OUT=<dataset de escritura> <opciones>; BY [DESCENDING] <variable/s a ordenar>; run; Si no indicamos dataset de escritura el output lo hará sobre el mismo dataset. Entre las opciones más destacadas emplearemos NODUPKEY para la eliminación de observaciones duplicadas. Ejemplo: data duplicados; input anio importe1; cards; 2001 345 2000 123 2000 123 2004 789 2002 456 2003 567 2003 567 ; run; proc sort data=duplicados nodupkey; by anio; run; Repasamos la ventana log:

SAS nos indica que ha eliminado dos observaciones de uno duplicadas.

7.2 PROC PRINT Este procedimiento imprime en la ventana output el contenido de un conjunto de datos. La sintaxis del procedimiento es la siguiente: PROC PRINT DATA=<dataset> <opciones>; TITLE <Título para la impresión>; VAR <variables a imprimir>; BY <variable de agrupación>; SUM <suma total de variable agrupada>; WHERE <condición>; RUN; Cabe destacar que hay sentencias comunes en los procedimientos como son BY, VAR o WHERE. El funcionamiento de BY ya lo hemos visto, nos sirve para agrupar variables; VAR es

Page 40: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

común para la práctica totalidad de procedimientos y con ello seleccionamos las variables del dataset que han de formar parte del procedimiento. Mención especial requiere la sentencia WHERE ya que con ella podemos hacer condiciones dentro de nuestros procedimientos. Ejemplo de uso: data anios; input anio importe1 importe2; cards; 2001 345 567 2000 123 234 2000 12 1098 2004 789 345 2002 456 21 2003 567 65 2003 67 2134 ; run; proc sort data=anios; by anio; run; proc print data=anios; var anio importe1; by anio; sum importe1; where anio<=2002; run; En la ventana output obtenemos:

Imprimimos dos variables del dataset anios agrupando por la variable año (siempre ordenada previamente) sumamos por importe1 y acotamos nuestra salida con WHERE para obtener todos los años inferiores o iguales a 2002.

7.3 PROC SUMMARY/MEANS: Son los procedimientos que emplearemos para la sumarización y los análisis descriptivos de variable. Por defecto estos procedimientos ofrecen la sumarización en la ventana output pero también podremos guardar estas salidas en datasets con distintas estructuras. La sintaxis de estos procedimientos es:

Page 41: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

PROC MEANS/SUMMARY DATA=<dataset> <opciones> <estadísticos>; BY <DESCENDING> variable-1 <... <DESCENDING> variable-n; CLASS variable(s) </opciones>; FREQ variable; ID variable(s); OUTPUT OUT=<dataset> <estadistico(s)=> </opciones> ; TYPES <tipo>; VAR variable(s) < / WEIGHT=variable peso>; WAYS list; WEIGHT <variable>; WHERE <condición>; QUIT; Con BY definimos los grupos (siempre ha de estar ordenado el conjunto de datos por esta variable). La instrucción CLASS identifica subgrupos para el análisis. FREQ identifica la variable de frecuencia. ID será de utilidad si generamos un dataset para identificar las variables generadas. OUTPUT genera un dataset, debemos especificar los estadísticos que seseamos obtener, la única diferencia entre MEANS y SUMMARY es que este último requiere esta sentencia ya que, por defecto, no ofrece salida en la ventana output. Con TYPES identificamos la combinación de las variables que introducimos en CLASS. VAR nos sirve para indicar sobre que variables es necesario el análisis. Con WAYS especificamos el número de combinaciones únicas de las variables CLASS. Por último con WEIGHT definimos la variable que asigna pesos. Comencemos a realizar ejemplos: data aleatorio; do i=1 to 200; grupo1=1; if mod(i,2)=0 then grupo1=2; if mod(i,3)=0 then grupo1=3; grupo2=rand("binomial",0.05,5); normal=rand("normal"); uniforme=rand("uniform")*1000; if grupo1=1 then uniforme=.; poisson=ranpoi(34,25); output; end; run; proc means data=aleatorio mean std; class grupo1 grupo2; var normal; quit; Mediante un bucle generamos un dataset con datos aleatorios sobre el que realizamos un procedimiento MEANS. Como estadístico queremos la media y la desviación típica (mean y std). Los grupos que clasifican el informe los marcan las variables grupo1 y grupo2, la única variable a analizar es la que representa una variable aleatoria con distribución normal 0-1. El resultado en la ventana output es:

Page 42: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Obtenemos un informe con la estructura que hemos especificado. Podemos mejorar nuestras salidas obteniendo resultados en formato HTML. Para ello tendremos que cambiar las preferencias: Si desmarcamos los resultados por listado y marcamos los resultados por HTML obtendremos salidas en formato web, para modificar el estilo podemos usar el combo destinado a tal efecto donde SAS ofrece muchas posibilidades, en el presente manual se empleará

Page 43: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

fundamentalmente el estilo MINIMAL. Por otro lado para generar conjuntos de datos SAS con los procedimientos trabajaremos con la instrucción OUTPUT: proc means data=aleatorio noprint; class grupo1 grupo2; var uniforme; output out=analis sum=suma; quit; proc print data=analis; run; El dataset generado tiene 15 observaciones, no genera salida porque hemos empleado la opción NOPRINT. Pero generamos el dataset analisis: En total el dataset generado tiene 15 observaciones: 1 el total (TYPE=0) + 3 para los niveles del grupo2 (TYPE=1) + 3 para los niveles del grupo1 (TYPE=2) + 3x3 por el cruce los niveles de los grupos 1 y 2. Tenemos 5 variables, las variables clasificatorias, los tipos, la frecuencia de las observaciones y el campo suma especificado en OUTPUT. Muy importante: MEANS no tiene en cuenta las observaciones con valores missing y por ello siempre obtendremos valores perdidos cuando operemos con ellos. Nuestro conjunto de datos requiere un tratamiento previo. Para generar conjuntos de datos SAS nuestros procedimientos MEANS/SUMMARY habitualmente tendrán una estructura parecida a este ejemplo en el que pretendemos hallar la diferencia entre lo observado con la variable poisson respecto de la media por grupos: proc sort data=aleatorio; by grupo1 grupo2; run; proc means data=aleatorio noprint nway; by grupo1 grupo2; var poisson; output out=analis (drop=_type_ _freq_) mean=media_poisson; quit; data aleatorio; merge aleatorio analis; by grupo1 grupo2; dif_medias = poisson/media_poisson - 1;

Total

Un solo grupo

Cruce de los 2 grupos

Page 44: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

run; Las opciones NOPRINT y NWAY serán fundamentales puesto que NOPRINT nos evita una salida innecesaria y NWAY se queda con el máximo valor de _TYPE_ que es el que nos interesa, el cruce del total de las variables. Habitualmente para la creación de datasets con información sumarizada emplearemos SUMMARY ya que este procedimiento, a diferencia de MEANS, no nos ofrece un output por pantalla si no que necesitaremos una sentencia OUTPUT. Estudiemos otro ejemplo para seguir descubriendo las posibilidades de sumarización: proc summary data=aleatorio missing nway; class grupo1 grupo2; var i normal uniforme; output out=sumarizados n(i)= sum(normal uniforme)= mean(poisson)=media_poisson; quit; Como comprobamos no es necesaria la opción NOPRINT en el procedimiento SUMMARY. Además podemos comprobar que en una misma sentencia output podemos obtener diferentes estadísticos con la estructura <estadístico>(<variable>)=<nombre_variable (opcional)>. En vista de las posibilidades de ambos procedimientos como regla de buen uso se puede establecer que: emplearemos MEANS cuando necesitemos una salida por pantalla y emplearemos SUMMARY cuando necesitemos generar un conjunto de datos SAS con información sumarizada de otro.

7.4 PROC FREQ Las tablas de frecuencias son una de las labores más habituales en el análisis de la información. En SAS para la creación de tablas de contingencia con información sumarizada contamos con el procedimiento FREQ. La sintaxis de este procedimiento es: PROC FREQ DATA=<dataset> <opciones>; BY <DESCENDING> variable-1 <...<DESCENDING> variable-n> <NOTSORTED>; EXACT <estadísticos> </ option(s)>; TEST <estadísticos> ; OUTPUT <estadísticos> OUT=<dataset>; TABLES <variable (requerido)> </opciones>; WEIGHT <variable></opciones>; QUIT; Muchas de las instrucciones que crean las sentencias que componen este procedimiento son análogas para procedimientos vistos con anterioridad. De las instrucciones nuevas tenemos EXACT empleada para los test de exactitud, TEST es empleada para los test de medida. TABLES es una instrucción necesaria para la correcta ejecución de FREQ y en ella indicaremos la/s variables que participan en nuestra tabla que siempre será de doble entrada. Para tablas de una entrada pondremos TABLES <variable-1> para doble entrada TABLES <variable-1>*<variable-2> conde <variable-1> irá en filas y <variable-2> en columnas; si escribimos TABLES <variable-1>*<variable-2>*<variable-3> obtendremos tantas variables de doble entrada como posibles valores tome <variable-3>. Comencemos a trabajar con ejemplos:

Page 45: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

data curso.datos; input COD :$10. ORG INICIO DEUDA; cards; 7212 1 200201 0 10194 1 200203 1 48442 1 200203 0 51756 1 200203 0 56495 1 200201 0 1011535 2 200202 0 1015550 2 200203 0 1019022 2 200203 0 1020732 2 200204 0 1023232 2 200203 0 1024731 2 200201 0 1025964 2 200210 0 1029595 2 200201 0 1030039 3 200201 0 1030368 3 200202 1 1031338 3 200202 0 1033218 3 200204 0 1034843 3 200203 0 1036047 3 200203 0 1040450 3 200203 0 1044481 3 200204 0 1032772 3 200204 0 ;run; proc freq data=curso.datos order=freq; title "Frecuencias por mes de inicio"; tables inicio; title "Frecuencias por organización y deuda"; tables org*deuda; quit; Obtenemos 2 tablas que irán ordenadas por la frecuencia:

Page 46: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Estas son las tablas (simple y de doble entrada) que por defecto podemos obtener con el procedimiento FREQ. Para el cálculo del test de la Ji-cuadrado empleamos la opción CHISQ: proc freq data=curso.datos order=freq; title "Frecuencias por organización y deuda"; tables org*deuda/chisq norow nocol; quit;

Si deseamos guardar los resultados obtenidos tras la realización de un procedimiento FREQ: proc freq data=curso.datos order=freq noprint; tables org*deuda/ out=frecuencias; quit; proc freq data=curso.datos order=freq noprint; tables org*deuda/chisq; output out=test_chi pchi lrchi n nmiss; quit; Con el primero de los ejemplos almacenamos en el dataset frecuencias la tabla de contingencia resultante de cruzar org con deuda. En el segundo ejemplo almacenamos en test_chi el resultado del test de la Ji-cuadrado resultante.

7.5 PROC DATASETS El PROC DATASETS sirve para administrar conjuntos de datos SAS. Entre las tareas de administración más comunes destacan:

• Copiar y pegar conjuntos de datos • Renombrar, reparar y borrar conjuntos de datos • Listar las tablas de una librería • Listar los atributos de las tablas • Crear o borrar índices en tablas • Concatenar dos conjuntos de datos SAS • ...

Page 47: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

La sintaxis de este procedimiento será: PROC DATASETS <opciones (*)>; APPEND BASE=<dataset> DATA=<dataset> <FORCE>; CHANGE antiguo_nombre1=nuevo_nombre2 ... antiguo_nombren=nuevo_nombren CONTENTS<opciones>; COPY OUT=libreria_2 ; DELETE <datasets>; MODIFY <datasets> <opciones>

INDEX CREATE <especificaciones de índices> INDEX DELETE índices | _ALL_; INFORMAT variable1 <informat1> <...variablen <informatn>>; LABEL variable1 <informat1> <...variablen <informatn>>; RENAME antiguo_nombre1=nuevo_nombre2 ... antiguo_nombren=nuevo_nombren

QUIT; (*)->Entre las opciones de este procedimiento destacan: LIBRARY para especificar la librería de trabajo. NODETAILS para evitar la salida en output, NOLIST para evitar información del directorio KILL para eliminar datasets. Con la instrucción APPEND concatenamos datasets (igual que si empleamos SET en un paso DATA), hemos de especificar la tabla BASE y la tabla que se anexa (DATA). Con CHANGE modificamos los nombres de datasets de la librería que indicamos con LIBRARY en las opciones. Con CONTENS listamos el contenido de la librería. Con DELETE eliminamos datasets de una librería. Con MODIFY modificamos los atributos de un dataset. Las modificaciones pueden ser:

• INDEX CREATE para crear índices compuestos y sencillos en una tabla SAS. • INDEX DELETE para eliminar índices en las tablas SAS. • INFORMAT para modificar el formato de lectura de las variables. • LABEL para modificar las etiquetas de las variables • RENAME para renombrar las variables

Simulemos una librería de ejemplo: libname temp "C:\temp"; data temp.polizas1; do indice = 1 to 2000; poliza=compress("POL"||put(indice,z5.)); prima=ranuni(45)*1000; output; end; data temp.polizas2; do indice = 2001 to 3000; poliza=compress("POL"||put(indice,z5.)); prima=ranuni(45)*1000;

Page 48: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

output; end; data temp.siniestros; drop j; do indice=1 to 3000; do j=1 to 3000; if ranuni(25)<0.00005 then do; poliza=compress("POL"||put(indice,z5.)); importe=ranuni(8)*2000; output; end; end; end; run; Mostremos su contenido: title "Contenido de temp"; proc datasets lib=temp; quit;

Anexemos el dataset polizas1 y polizas2: proc datasets lib=temp nodetails nolist;

append base=polizas1 data=polizas2; quit;

Modifiquemos los atributos de las variables de polizas1: proc datasets lib=temp nodetails nolist; modify polizas1; rename poliza=pol prima=pr; label pol="Póliza contratada"; quit;

Page 49: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

7.6 PROC IMPORT/EXPORT En el capitulo 5.1.2 Lectura de ficheros de texto vimos como importar ficheros planos a conjuntos de datos SAS con el asistente que, al final, generaba un código SAS, un paso DATA que nos permitía modificar los atributos de las variables leídas. Otra forma de importar datos es el procedimiento IMPORT. La sintaxis es: DATAFILE="filename" | TABLE="tablename" OUT=<dataset> <opciones> <DBMS=identificador>; <código específico> ; QUIT; En DATAFILE indicamos el fichero a leer, bien sea una hoja Excel, una tabla Access o un fichero delimitado. Importante: Tanto la importación de ficheros de Excel como tablas Acces implica tener licenciado el módulo SAS ACCESS TO PC FILES. Con la instrucción TABLE indicamos el nombre de la tabla de BBDD a leer si es necesario. En OUT indicamos el dataset que pretendemos generar. La sintaxis para el procedimiento EXPORT es análoga: PROC EXPORT DATA=<dataset> <opciones> OUTFILE="filename" | OUTTABLE="tablename" DBMS=<identificador> <REPLACE>; <código específico>; QUIT; En DATA indicamos el dataset a exportar y en OUTFILE indicamos el fichero a generar, si fuera una BBDD ACCESS necesitamos el nombre de la tabla con la opción OUTTABLE=. Una instrucción análoga para los dos procedimientos es DBMS= con ella señalamos el tipo de fichero que leemos/escribimos, los tipos más habituales son pueden ser: DBMS= Identificador Extensión SAS

BASE ACCESS Microsoft Access 2000 or 2002 table .mdb ACCESS97 Microsoft Access 97 table .mdb ACCESS2000 Microsoft Access 2000 table .mdb ACCESS2002 Microsoft Access 2002 table .mdb CSV delimited file (comma-separated values) .csv x DLM delimited file (default delimiter is a blank) .* x EXCEL Excel 2000 or 2002 spreadsheet .xls EXCEL4 Excel 4.0 spreadsheet .xls EXCEL5 Excel 5.0 or 7.0 (95) spreadsheet .xls EXCEL97 Excel 97 or 7.0 (95) spreadsheet .xls EXCEL2000 Excel 2000 spreadsheet .xls EXCEL2002 Excel 2002 spreadsheet .xls TAB delimited file (tab-delimited values) .txt x

Page 50: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Para la utilización de códigos con los procedimientos IMPORT/EXPORT es recomendable emplear el asistente. Si recordamos el capítulo 5.1.2 en un paso del asistente teníamos la siguiente ventana:

En este punto podemos indicarle SAS donde queremos que nos genere el código SAS y posteriormente emplearlo en nuestro programa. El código generado por el asistente para exportar una tabla SAS a un fichero de Excel sería: PROC EXPORT DATA= TEMP.Siniestros OUTFILE= "C:\temp\fichero_siniestros.xls" DBMS=EXCEL2000 REPLACE; SHEET="tabla"; RUN; Si deseamos importar este mismo fichero: PROC IMPORT OUT= WORK.siniestros2 DATAFILE= "C:\temp\fichero_siniestros.xls" DBMS=EXCEL2000 REPLACE; SHEET="tabla"; GETNAMES=YES; RUN;

7.7 PROC TRANSPOSE El TRANSPOSE lo emplearemos para transponer tablas SAS. Es habitual que dispongamos de tablas con múltiples registros para un campo clave. Por ejemplo información año a año para un cliente: Para esta tarea disponemos del PROC TRANSPOSE cuya sintaxis es: PROC TRANSPOSE DATA=<dataset> OUT=<dataset> <PREFIX=prefix>; BY <DESCENDING> variable-1 <...<DESCENDING> variable-n> ; COPY variable; ID variable;

Cliente Año ImporteA001 2004 100A001 2005 110A001 2006 121 Cliente importe2004 importe2005 importe2006 importe2007A001 2007 133,1 A001 100 110 121 133,1A002 2004 125 A002 125 143,75 158,125 173,9375A002 2005 143,75A002 2006 158,125A002 2007 173,9375

Page 51: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

VAR variable(s); QUIT; Especificamos dataset de entrada y salida, con PREFIX= prefijamos los nombres de la variables a transponer. En BY tenemos la variable agrupadora. Con COPY copiamos directamente una variable en el dataset de salida. En ID marcamos el campo que nos identifica las nuevas variables a transponer, variables que irán en VAR. Como ejemplo tenemos: data clientes; input Cliente $5.Anio Importe; segmento=substr(cliente,1,1); cards; A001 2004 100 A001 2005 110 A001 2006 121 A001 2007 133.1 A002 2004 125 A002 2005 143.75 A002 2006 158.125 A002 2007 173.937 B003 2004 300 B003 2005 345 B003 2006 379.5 B003 2007 417.45 B004 2004 250 B004 2005 287.5 B004 2006 316.25 B004 2007 347.875 ; run; proc sort data=clientes; by cliente; run; proc transpose data=clientes out=tclientes prefix=importe; by cliente; id anio; quit; La transposición queda:

Page 52: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Por defecto TRANSPOSE pone el nombre de la anterior variable que podemos eliminar con DROP= como opción de escritura: proc transpose data=clientes out=tclientes (drop=_name_) prefix=importe; by cliente; id anio; quit;

7.8 PROC UNIVARIATE El UNIVARIATE es un procedimiento de SAS que nos permite conocer la distribución de una variable, para ello nos ofrece métodos y medidas estadísticas y una serie de gráficos de alta resolución. La sintaxis de este procedimiento es: PROC UNIVARIATE <option(s)>; BY <DESCENDING> variable-1 <... <DESCENDING> variable-n; CLASS variable(s) </opciones>; FREQ variable; ID variable(s); OUTPUT OUT=<dataset> <estadistico(s)=> </opciones> ; HISTOGRAM <variable(s)> </ opciones >; PROBPLOT <variable(s)> </ opciones >; QQPLOT <variable(s)> </ opciones >; INSET <opciones>; VAR variable(s); WEIGHT variable; QUIT; El funcionamiento de by, CLASS, FREQ, ID, OUTPUT, VAR y WEIGHT es análogo a lo visto en los procedimientos anteriores. Como instrucciones novedosas tenemos HISTOGRAM que nos permite generar histogramas, PROBPLOT nos ofrece gráficos de funciones de probabilidad y QQPLOT crea gráficos de cualtil-cuantil. INSET añade elementos a nuestras salidas o conjuntos de datos SAS. Comencemos a trabajar con este procedimiento y analicemos las salidas que nos ofrece por defecto: /*DATASET ALEATORIO PARA EL ESTUDIO DE DISTRIBUCIONES*/ data aleatorio; do i=1 to 200; grupo1=1; if mod(i,2)=0 then grupo1=2; if mod(i,3)=0 then grupo1=3; grupo2=rand("binomial",0.05,5); normal=rand("normal"); uniforme=rand("uniform")*1000; if grupo1=1 then uniforme=.; poisson=ranpoi(34,25); output; end; run; proc univariate data=aleatorio; var uniforme; quit;

Page 53: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

En el navegador de resultados tenemos:

Podemos navegar por todos los resultados de la ejecución del procedimiento. En el output tenemos:

Page 54: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

UNIVARIATE nos ofrece cuadros con medidas estadísticas básicas de posición, dispersión y asimetría. Test de posición para la media = 0 y los cuantiles de la variable en estudio. Añade un cuadro para el estudio de los valores extremos y los valores ausentes (si los hubiera). Esta información nos permite conocer la distribución que tiene una variable, pero además contamos con posibilidades gráficas para mejorar nuestros estudios:

Page 55: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

proc univariate data=aleatorio; title "Estudio de la variable Poisson aleatoria"; var poisson; histogram poisson/ normal(noprint) cbarline=red midpoints=10 to 40 by 5; quit; Además de todas las tablas anteriores para la variable poisson SAS nos ofrecerá un histograma con la distribución de la variable con determinadas opciones que pueden resultarnos muy interesantes.Con NORMAL SAS nos dibujará la línea de la distribución normal, con NOPRINT evitamos obtener todos los test de distribución. La opción CBARLINE nos permite dar un color las barras de nuestro histograma,por último con MIDPOINTS especificamos el acho de rango del histograma. El gráfico obtenido es:

A la vista de este gráfico podemos concluir que 200 valores aleatorios de una variable con distribución de Poisson convergen en una distribución normal. Para un mejor estudio de la variable podemos emplear los gráficos cualtil-cuantil: proc univariate data=aleatorio; title "Poisson aleatoria converge a normal"; var poisson; qqplot poisson/ normal(mu=est sigma=est) cframe=grey; inset mean var / cfill=red header='Param. dist. normal' position=(95,10) refpoint=br; quit; Realizamos un gráfico cuantil-cuantil en el que comparamos con una función normal, queremos que la superficie del gráfico sea gris. Además con INSET le añadimos al gráfico la media y la varianza en un cuadro en el que determinamos la posición y la cabecera. El resultado obtenido es:

Page 56: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Tenemos otra potente herramienta para analizar las distribuciones de las variables. El funcionamiento de la instrucción PROBPLOT es muy similar: proc univariate data=aleatorio; title "Poisson aleatoria no sigue dist. Gamma"; var poisson; probplot poisson/ gamma(alpha=est); quit;

Page 57: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Otra opción gráfica interesante del PROC UNIVARIATE es la posibilidad de obtener más de un gráfico en una salida, por ejemplo si deseamos realizar un histograma de la variable poisson por grupo: proc univariate data=aleatorio; title "Poisson por grupo"; class grupo1 grupo2; var poisson; histogram poisson/ nrows=3 ncol=3 normal(noprint) cbarline=red midpoints=10 to 40 by 5 vaxislabel="Grupo 1" ; quit;

Con las opciones NROWS y NCOLS especificamos el número de gráficos que deseamos en nuestra salida, en este caso 3 x 3. Si deseamos guardar resultados con el proc univariate emplearemos la instrucción OUTPUT como en otros procedimientos antes estudiados, un ejemplo de sintaxis es: proc univariate data=aleatorio; class grupo1 grupo2; var poisson; output out=salida median=mediana p5=percent_5 p95=percent_95; quit; Muy similar a los procedimientos SUMMARY/MEANS pero con la posibilidad de guardar los percentiles, además podemos especificar un rango de percentiles a volcar en el conjunto de datos SAS:

Page 58: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

proc univariate data=aleatorio; class grupo1 grupo2; var poisson; output out=salida pctlpre=salida pctlpts=0 to 100 by 1; quit; Con la opción PCTLPRE marcamos el dataset al que queremos añadir los percentiles, con la oción PCTLPTS especificamos que percentiles deseamos, en este caso del 0 al 100 de uno en uno, si vemos el log:

Hemos generado un dataset salida con 103 variables, grupo1, grupo2 y 101 percentiles de la variable poisson del 0 al 100.

Page 59: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Page 60: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

8. PROC SQL Este procedimiento implementa el lenguaje SQL en SAS. Con este procedimiento podremos:

• Seleccionar o sumarizar columnas de tablas SAS y presentarla en la ventana output.

• Crear o manipular datos SAS: o Sumarizar o Cruzar o Modificar

• Conectarnos a otros sistemas de información (database management system: DBMS)

y tranformar esta información en datos SAS. La sintaxis es: PROC SQL <opciones>; ALTER TABLE tabla <ADD <CONSTRAINT> clave <ADD columna> <DROP CONSTRAINT clave> <DROP columna> - <MODIFY columna> ; CREATE <UNIQUE> INDEX índice ON tabla ( columna1,…,columnaN); CREATE TABLE tabla (especificaciones de columnas|clave) ; CREATE TABLE tabla1 LIKE tabla2; CREATE TABLE tabla AS consulta <ORDER BY campo1,..,campoN>; CREATE VIEW vista AS consulta <ORDER BY campo1,..,campoN>; DESCRIBE TABLEt tabla ; DESCRIBE VIEW vista; DROP INDEX índice1,…,índiceN FROM tabla; DROP TABLE tabla1,…,tablaN; DROP VIEW tabla1,…,tablaN; SELECT <DISTINCT> columnas FROM tabla <WHERE condición(es)> <GROUP BY variable_agrupadora1,…,variable_agrupadoraN <HAVING condición(es)> <ORDER BY columna1,…,caolumnaN; UPDATE tabla <AS alias> SET column=expresión SQL <SET column=expresión SQL <WHERE expresión SQL >; VALIDATE expresión SQL; QUIT;

SQL

DBMS

SAS

DBMS

SAS

Page 61: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

• ALTER TABLE lo emplearemos para el trabajo con campos de tablas • CREATE INDEX nos crea índices simples y compuestos en nuestras tablas • CREATE TABLE crea tablas • CREATE VIEW crea vistas • DELETE borra filas • DESCRIBE describe • DROP elimina tablas o índices • SELECT selecciona • UPDATE actualiza • VALIDATE valida las consultas

Como vemos las posibilidades del PROC SQL son muy extensas ya que abarca todas las tareas que se pueden realizar con el lenguaje SQL. Importante: el lenguaje SQL de SAS no es estándar tiene algunas particularidades que le distinguen de SQL. En el presente manual nos centraremos en ejemplos de código para consultas de selección y ejemplos de cruces de tablas a través de SQL.

8.1 Consultas de selección La base de las consultas de selección será la instrucción SELECT cuya sintaxis en SAS se puede resumir en: PRC SQL; SELECT <DISTINCT> campo1,…,campoN FROM tabla1,…,tablaN <WHERE condiciones> <GROUP BY campo_agrupador1,…,campo_agrupador2> <HAVING condiciones> <ORDER BY campo1,…,campoN>; QUIT; Como vemos campos y tablas se separan con , pero hay una serie de palabras clave que marcan el final de un bloque de instrucciones y el comienzo de otro. Todas las consultas finalizarán con ; Podremos realizar selecciones de campos de una tabla bajo unas condiciones y también podremos sumarizar campos agrupados por otros de una tabla con sus condiciones correspondientes. Para comprender mejor la estructura del PROC SQL vamos a dividir las consultas en “bloques de código”.

8.1.1 “Bloques” que componen una consulta

Recuperando ejemplos anteriores en los que generábamos un conjunto de datos SAS aleatorio con variables cualitativas (agrupadas) y cuantitativas comenzamos a trabajar con consultas de selección para conocer mejor la estructura del PROC SQL: data aleatorio; do i=1 to 200; grupo1=1; if mod(i,2)=0 then grupo1=2; if mod(i,3)=0 then grupo1=3; grupo2=rand("binomial",0.05,5); normal=rand("normal"); uniforme=rand("uniform")*1000; if grupo1=1 then uniforme=.; poisson=ranpoi(34,25); output; end; run;

Page 62: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

/*CONSULTA DE SELECCION*/ proc sql; select /*BLOQUE DE SELECCION DE CAMPOS*/ grupo1, grupo2, poisson /*BLOQUE FROM DONDE ELEGIMOS LA TABLA*/ from aleatorio /*BLOQUE WHERE PARA ESTABLECER LAS CONDICIONES*/ where i<10 and poisson<30; quit; El código SAS SQL se puede dividir en distintos bloques, el inicio y el fin de cada bloque lo marcarán determinadas palabras clave. En el ejemplo tenemos un bloque de selección de campos que comienza con SELECT, un bloque donde especificamos la tabla a leer que comienza con FROM y un bloque donde establecemos las condiciones de lectura que marca la palabra WHERE. Tanto SELECT como FROM son sentencias obligatorias para las consultas de selección. En el siguiente código de ejemplo vamos a realizar una consulta de selección con información agrupada: /*CONSULTA DE SELECCION CON DATOS AGRUPADOS*/ proc sql; title "Ejemplo de consulta de sumarización"; select /*BLOQUE DE SELECCION DE CAMPOS*/ grupo1, grupo2, count(i) as observaciones, mean(poisson) as media_poisson /*BLOQUE FROM DONDE ELEGIMOS LA TABLA*/ from aleatorio /*BLOQUE WHERE PARA ESTABLECER LAS CONDICIONES*/ where poisson<50 /*BLOQUE DE AGRUPACION*/ group by grupo1,

grupo2 /*BLOQUE DE ORDENACION*/ order by calculated observaciones; quit; Nuestra consulta selecciona 4 campos de nuestra tabla: grupo1, grupo2, cuenta de i a la que asignamos con AS el alias observaciones y media de poisson cuyo alias será media_poisson. La instrucción AS siempre asigna un alias a los campos del bloque de la selección. Estos dos últimos campos son sumarizaciones sobre los dos primeros. Para realizar conteos emplearemos COUNT(<variable>) y para el cálculo de la media la función MEAN (<variable>). La tabla de la que seleccionamos será aleatorio, en WHERE filtramos sólo las observaciones con un valor para poisson menor de 50 y añadimos un nuevo bloque a nuestra consulta en el que especificamos las variables de agrupación, estos bloques de agrupación siempre comenzarán con la instrucción GROUP BY. La instrucción ORDER BY marcará el comienzo de los bloques de ordenación. Como particularidad indicar que si necesitamos referenciar variables calculadas en nuestra selección, en nuestro ejemplo queremos ordenar la consulta por el número de observaciones, tendremos que emplear la instrucción calculated. El resultado obtenido será:

Page 63: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

3 valores de grupo1 x 3 valores de grupo2 dan como resultado 9 registros con 2 variables sumarizadas observaciones (que además ordenará la selección) y media_poisson. En el ejemplo hemos empleado las funciones de sumarización COUNT y MEAN pero contamos con más funciones, las más habituales serán: proc sql; title "Funciones habituales de sumarización"; select grupo1, grupo2, count(poisson) as cuenta_poisson, count(distinct poisson) as cuenta_dist_poisson, max(poisson) as max_poisson, min(poisson) as min_poisson, mean(poisson) as media_poisson, std(poisson) as desviacion_poisson, sum(poisson) as suma_poisson from aleatorio group by grupo1, grupo2; quit;

Con la función COUNT contamos registros, si empleamos COUNT(DISTINCT <variable>) contamos los valores distintos para la variable. El resto de funciones son análogas a las empleadas en un procedimiento MEANS. Para este ejemplo no hemos empleado el bloque de ordenación por lo que el orden vendrá marcado por el bloque de agrupación, es decir, GROUP BY marca el orden ascendente.

Page 64: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Podemos anidar funciones de sumarización con funciones aritméticas dentro de una misma columna, si, por ejemplo, deseamos realizar una media ponderada deberemos sumar el producto del valor y el peso y dividir por el peso: proc sql; title "Media ponderada por normal, en casos positivos"; select grupo1, grupo2, sum(poisson*normal)/sum(normal) as media_ponderada from aleatorio where normal > 0 group by grupo1,grupo2; quit; El mismo campo con alias media_ponderada viene de la sumarización de una operación aritmética entre la sumarización de una normal, con selecciones de este tipo podemos calcular la media ponderada.

8.1.2 Campos de selección condicionales (CASE)

Dentro del bloque de selección de columnas podemos crear campos condicionales con la instrucción CASE. En el ejemplo con el que venimos trabajando si deseamos agrupar más una de las variables grupo podemos emplear una sentencia condicional: proc sql; title "Ejemplo de uso de CASE"; select grupo1, case when grupo2<=1 then "tipo 0-1" else "tipo 2" end as nuevo_grupo2, sum(distinct poisson) as suma_distintas_poisson from aleatorio group by 1,2; quit;

Observemos la sintaxis de CASE: CASE WHEN condición1 THEN valor1 ... WHEN condiciónN THEN valorN ELSE valorN+1 END Con CASE indicamos el inicio de la sentencia condicional. Cada condición irá marcado con WHEN, en el último caso emplearemos ELSE y es necesario marcar el final de la condición con END. En este ejemplo estamos reagrupando dos valores de una variable. También tenemos más particularidades importantes en esta consulta: SUM(DISTINCT <variable>) nos permite sumar distintos valores, DISTINCT se puede emplear para todas las funciones y por

Page 65: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

otro lado en el bloque de agrupación tenemos sustituidos los valores de las variables por la posición que ocupan dentro del bloque de selección; esto nos será de gran utilidad para mejorar nuestros códigos. De nuevo reiterar que sin bloque de ordenación el bloque de agrupación nos marca el orden. En las sentencias condicionales podemos emplear tanto variables agrupadoras como variables continuas o la combinación de ambos tipos de variables. De este modo si deseamos crear un grupo que sea la combinación de ambas variables de agrupación y otro grupo que vaya en función de una variable continua que toma valores positivos y negativos podemos hacer: proc sql; title "Ejemplo de uso de CASE"; select /*CONDICIONALES NUMERICAS*/ case when normal<0 then "NEGATIVA" else "POSITIVA" end as signo_normal, /*MEZCLA DE CONDICIONALES*/ case when poisson>30 then "TIPO x-30" when grupo1<=2 then "TIPO 2-30" else "TIPO 3-x" end as nuevo_grupo, min(poisson) as min_poisson, max(poisson) as max_poisson, sum(uniforme) as suma_uniforme from aleatorio group by calculated signo_normal, calculated nuevo_grupo; quit;

En este ejemplo hemos planteado distintas formas de crear sentencias condicionales. Además en este ejemplo se aprecia como CASE genera grupos excluyentes en función del orden en el que pongamos las condiciones, analicemos la segunda sentencia CASE para comprender el funcionamiento: /*MEZCLA DE CONDICIONALES*/ case when poisson>30 then "TIPO x-30" A todos los que tengan un valor mayor que 30 para la variable poisson los asigna el tipo x-30. when grupo1<=2 then "TIPO 2-30" En otro caso, a todos los que tengan un valor inferior a 2 para grupo1 y además tengan un valor menor de 30 para poisson entonces el tipo es tipo 2-30.

Page 66: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

else "TIPO 3-x" end as nuevo_grupo, Si no se cumple nada de lo anterior entonces el valor es tipo 3-x. Las condiciones son excluyentes hacia abajo. Si una observación ya ha entrado a un valor éste no se modifica. Otra particularidad de nuestro ejemplo la tenemos en la sentencia GROUP BY donde, en este caso, no hemos puesto el orden de las variables agrupadoras, por lo que nuestro código ha necesitado de la cláusula CALCULATED para indicar que estamos ante variables calculadas en nuestra consulta de selección.

8.1.3 Uso de sentencias lógicas y condicionales

Internamente SAS traduce sentencias lógicas en un valor 0 (falso) o 1 (verdadero). Estos valores son numéricos por lo que se puede trabajar con ellos: data _null_; y=0; do i = 1 to 100; x=rannor(2)>0; y=y+x; end; put "Número de positivos en 100 aleatorios de distribución uniforme: " y; run;

Podemos tanto agrupar como sumarizar campos condicionales mediante SQL ya que al final estamos trabajando con valores 0-1. Veamos un ejemplo de este tipo de consultas: proc sql; title "Ejemplo de uso de instrucciones condicionales"; select grupo1, normal>0 as normal_positiva, sum(poisson>30) as poisson_mayor_30, sum(uniforme is not null) as uniformes_no_nulas, count(*) as observaciones from aleatorio group by grupo1, calculated normal_positiva; quit; Las variables de agrupación serán grupo1 y 1 si la normal es positiva y 0 si es negativa será el campo con el alias normal_positiva. Como variables de sumarización tendremos la suma de los valores de la poisson mayores que 30, la suma de los valores de la uniforme que no sean nulos y la cuenta del total de los registros. Esta consulta dará como resultado:

Page 67: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Reiteramos que normal_positiva toma valores 0 o 1 y poisson_mayor_30 sumará 1 cada vez que sea verdadera la condición (poisson>30). El trabajo con este tipo funciones lógicas nos permite trabajar con campos que antes estaban en “modo fila” (varios registros por valor). Ahora trabajaremos en “modo columna” (valores por columna). Por ejemplo, si deseamos calcular el porcentaje de valores de poisson mayores que 30 deberemos hacer: proc sql; title 'Ejemplo de trabajo en "modo columna"'; select grupo1, normal>0 as normal_positiva, count(*) as observaciones, sum(poisson>30)/count(*) as porcent_mayor30 format percent5.2 label='Portentaje mayores 30' from aleatorio group by 1,2; quit; Vemos que en este ejemplo hemos trabajado con dos sumarizaciones en la misma columna de modo que podemos obtener el un porcentaje como resultado de una operación aritmética. Además es posible modificar los atributos de la variable en el mismo procedimiento SQL, hemos asignado un formato de porcentaje y una etiqueta tras asignarle el alias. Destacar que, para la agrupación, hemos empleado la nomenclatura “posición en selección”, el resultado es:

Al igual que podemos sumarizar operaciones lógicas también podemos sumarizar sentencias condicionales siempre que manejemos valores numéricos. Como siempre, entendamos esta metodología con un ejemplo: proc sql; title "Sumarización de condiciones"; select

Page 68: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

grupo1, /*SUMARIZAMOS UNA CONDICION*/ sum( case when grupo2=0 then 0 when grupo2=1 then poisson when grupo2=2 then poisson*2 else poisson*3 end) as poisson_por_peso from aleatorio group by 1; quit; Para cada valor de grupo2 le asignamos un valor diferente a poisson y los valores que va tomando los podemos sumarizar. Esta metodología es muy práctica a la hora de asignar pesos a las observaciones. El resultado queda:

8.2 Consultas de creación de tablas con PROC SQL Para crear tablas SAS a partir del PROC SQL sólo hemos de añadir un nuevo bloque a nuestras consultas: /*CONSULTA DE CREACION DE TABLA*/ proc sql; /*BLOQUE DE CREACION DE TABLAS*/ create table seleccion as /*BLOQUE DE SELECCION DE CAMPOS*/ select grupo1, grupo2, count(i) as observaciones, mean(poisson) as media_poisson /*BLOQUE FROM DONDE ELEGIMOS LA TABLA*/ from aleatorio /*BLOQUE WHERE PARA ESTABLECER LAS CONDICIONES*/ where poisson<50 /*BLOQUE DE AGRUPACION*/ group by grupo1, grupo2 /*BLOQUE DE ORDENACION*/ order by calculated observaciones; quit; A nuestras consultas de selección le añadimos la sentencia CREATE TABLE <tabla SAS> AS y ya estaremos creando una nueva tabla, un nuevo conjunto de datos SAS cuyas variables serán las especificadas en el bloque de selección y que vendrán de la tabla del bloque de selección con las condiciones, las sumarizaciones y las ordenaciones que deseemos.

Page 69: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

También podemos crear tablas SAS estableciendo primero la estructura e introduciendo los valores con la instrucción INSERT INTO: libname temp "c:\temp"; proc sql; create table temp.ejemplo (Id char(4), sexo char(1), codigo char(3), importe num, f_inicio num informat=date7. format=date7., f_fin num informat=date7. format=date7.); insert into temp.ejemplo values('1639','F','TA1',42260,'26JUN07'd,'28JAN08'd) values('1065','M','ME3',38090,'26JAN07'd,'07JAN08'd) values('1400','M','ME1',29769,'05NOV07'd,'16OCT08'd) values('1561','M',null, 36514,'30NOV07'd,'07OCT08'd) values('1221','F','FA3',.,'22SEP07'd,'04OCT08'd); title 'Prefiero un paso DATA'; select * from temp.ejemplo; quit; Disponiendo de los pasos DATA esta forma de crear tablas SAS no es muy empleada. Habitualmente nuestras tablas serán selecciones de otras tablas SAS, estas selecciones pueden ser de una única tabla SAS o del cruce de múltiples tablas mediante SQL. Todas las sintaxis analizadas en el capítulo anterior pueden generar datasets añadiendo el bloque de creación de tablas. En este capítulo vamos a estudiar algunas de las tareas más habituales de uso del PROC SQL. Una de las labores más frecuentes con SQL es la selección de distintos valores para ello emplearemos DISTINCT en el bloque de selección: /*CONSULTA DE CREACION DE TABLA*/ proc sql; /*BLOQUE DE CREACION DE TABLAS*/ create table seleccion as /*BLOQUE DE SELECCION DE DISTINTOS CAMPOS*/ select distinct grupo1 format z2. label="Valores de grupo", put(poisson,z5.) as poisson length=5 /*BLOQUE FROM DONDE ELEGIMOS LA TABLA*/ from aleatorio /*BLOQUE WHERE PARA ESTABLECER LAS CONDICIONES*/ where poisson<50 /*BLOQUE DE ORDENACION*/ order by poisson; quit; Con DISTINCT seleccionamos los distintos registros para los campos seleccionados, con esta instrucción nos garantizamos no tener duplicados. En esta consulta de creación de tabla también podemos analizar como se modifican los atributos de las variables. Podemos asignar formatos, etiquetas y longitudes tras escribir la columna seleccionada y el alias (si fuera necesario). Tanto LABEL como LENGTH necesitan el signo = para funcionar. De nuestro programa también destaca el uso de la función PUT para transformar poisson en una variable

Page 70: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

alfanumérica. Importante: En los procedimientos SQL de SAS podemos emplear todas las funciones SAS, no estamos acotados sólo a las funciones habituales de SQL: proc sql; create table funciones as select missing(uniforme) as perdidos_uniforme,

input(substr(left(put(uniforme,8.)),1,1),3.) as primera_cifra_uniforme,

reverse(put(poisson,3.)) as inversa_poisson, sum(index(put(normal,8.),"1")) as normales_con_1 from aleatorio where abs(normal) > 0.5 group by 1,2,3; quit; Todas las funciones disponibles en SAS se pueden emplear en los procedimientos SQL. Importante: Siempre que generemos un conjunto de datos SAS es necesario asignarle el alias con AS si no se lo asignamos SAS pondrá por defecto los nombres a las variables, estos nombres serán: TEMG001 … TEMG00N. Al igual que en un paso DATA podíamos emplear opciones de lectura y escritura en el PROC SQL podemos hacer lo mismo. En el ejemplo que estamos manejando, si quisiéramos seleccionar todas las variables de aleatorio excepto poisson: proc sql; create table aleatorio_sin_poisson as select a.* from aleatorio (drop=poisson) as a; quit; Con las opciones de lectura/escritura nos evitamos tener que escribir todas las variables en el bloque de selección. Una particularidad muy importante del ejemplo anterior es el alias de la tabla del bloque FROM. Al igual que asignamos alias a las variables en la selección es importante asignar alias a las tablas de las que se leen los datos. La forma de asignar alias a tablas es igual que en campos, <dataset> AS <alias>. Pero en este caso los alias serán internos a la consulta, es decir, no modificamos el nombre ni la estructura del dataset, simplemente lo referenciados dentro de nuestra consulta. Otro elemento destacado del ejemplo anterior es la estructura <alias>.*, se emplea para referirnos a la totalidad de los campos de la tabla. Como vimos en el capítulo 5.3 la instrucción WHERE puede funcionar como una opción de lectura/escritura. Si le empleamos como opción de escritura obtenemos un elemento muy potente para la realización de consultas anidadas de creación de tablas. Entendamos esta metodología con un ejemplo: proc sql; create table maximos as select /*CAMPO DE AGRUPACION*/ poisson, /*SUMARIZAMOS DOS VARIABLES*/ max(int(uniforme)) as max_entera_uniforme, count(*) as observaciones from aleatorio group by 1; quit; data maximos; set maximos; where max_entera_uniforme>500; run;

Page 71: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Hacemos una subselección de una consulta, pero necesitamos un paso SQL y un paso DATA. Esto se puede hacer en la misma consulta SQL empleando WHERE= como opción de escritura: proc sql; create table maximos (where=(max_entera_uniforme>500)) as select poisson, max(int(uniforme)) as max_entera_uniforme, count(*) as observaciones from aleatorio group by 1; quit; Con esta metodología tenemos una herramienta muy sencilla y potente para la realización de selecciones anidadas con un código bastante sencillo.

8.3 Uniones de tablas Otra de las operaciones más habituales con el procedimiento SQL de SAS será el la unión o el cruce de tablas SAS. Los tipos de uniones serán los mismos que los estudiados en el capítulo 6 (uniones de conjuntos de datos SAS):

• Unión vertical: o Concatenación: o Intercalación:

• Unión horizontal

8.3.1 Uniones verticales

En el lenguaje SAS disponemos del paso DATA con SET para hacer uniones verticales, en SQL disponemos de la cláusula UNION para realizar consultas de datos anexados. Para conocer la sintaxis vamos a replicar los ejemplos anteriormente empleados para las uniones a través de pasos DATA. Para el caso de la concatenación uníamos 2 conjuntos de datos con 5 y 3 observaciones con la misma variable, el resultado era un dataset con una única variable y 8 observaciones: data uno; input anio ; cards; 2000 2001 2002 2003 2004 ; run; data dos; input anio ; cards; 2005 2006 2007 ; run; proc sql; create table tres as select

Page 72: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

a.* from uno as a union select b.* from dos as b; quit; proc sql; select * from tres; quit; Con UNION realizamos la concatenación de los dos conjuntos de datos SAS:

En principio la sintaxis de un paso DATA es más sencilla que la empleada con SQL, no es habitual emplear esta metodología para unir anexar conjuntos de datos SAS. En el ejemplo de intercalación de conjuntos de datos SAS partíamos de dos datasets con 5 observaciones y 2 variables cada uno: data uno; input anio importe; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data dos; input anio importe; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sql; create table tres as select * from uno union select * from dos order by anio ,importe descending; select * from tres; quit; Con el PROC SQL las intercalaciones las llevaremos a cabo con UNION y una posterior ordenación por el campo de intercalación. En este ejemplo para replicar la salida antes obtenida a través del paso DATA con SET+by hemos necesitado ordenar también descendentemente por la variable importe ya que en este caso el orden de las tablas en la consulta de creación de tabla no influye en la selección:

Page 73: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Las uniones verticales con SQL requieren de la utilización de UNION en las consultas, se podría establecer una equivalencia al SET del paso DATA. Cabe destacar que podemos unir verticalmente con SQL más de 2 conjuntos de datos SAS.

8.3.2 Uniones horizontales (joins)

Para las uniones horizontales en el PROC SQL tenemos un potente aliado. En el paso DATA disponemos de MERGE para este tipo de uniones. En SQL disponemos de varios tipos de joins:

• Inner join: Une registros por campos coincidentes. • Outer join: Une o no por campos coincidentes. • Natural join: Une por campos coincidentes con unas determinadas características.

Estas 3 herramientas de código son las que emplearemos para la unión de tablas con el PROC SQL. Para conocer mejor su funcionamiento y su sintaxis trabajaremos con el mismo ejemplo y analizaremos los distintos resultados obtenidos. Las tablas de partida para el estudio de estos cruces se crean con los siguientes programas: data tabla_izquierda; input anio importe1; cards; 2001 345 2000 123 2004 789 2002 456 2003 567 ; run; data tabla_derecha; input anio importe2; cards; 2003 45 2000 23 2001 79 2005 46 2006 67 ; run; proc sql; title "Tabla izquierda"; select * from tabla_izquierda; title "Tabla derecha"; select * from tabla_derecha; quit;

Page 74: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

8.3.2.1 Inner join Este tipo de cruce de tablas es la combinación de todos los registros de una tabla con todos los registros de otra(s), con inner join podemos unir de 2 a n tablas. Su sintaxis no es especial, sólo debemos separar en el bloque FROM todas las tablas a cruzar con una (,) y se lleva a cabo la consulta. El más básico de este tipo de cruces será el producto cartesiano de dos tablas, “todos por todos”: proc sql; create table cartesiano as select izq.*, der.* from tabla_izquierda as izq, tabla_derecha as der; quit; El resultado de este cruce de creación de tabla serán todos los registros de tabla_izquierda por todos los registros de tabla_derecha 5x5=25 registros. El análisis del log nos ofrece varios comentarios interesantes:

Log nos indica que estamos ante un producto cartesiano. También que la variable anio ya está en nuestra tabla, en este caso hace referencia a anio de la tabla_izquierda, la primera que se introdujo en el bloque de selección de la consulta. Como hemos comentado el resultado final son 25 observaciones. Para mejorar los cruces por inner join deberemos jugar con la cláusula WHERE. Por ejemplo la intersección entre ambas tablas sería: proc sql; select izq.*, der.* from tabla_izquierda as izq, tabla_derecha as der

Page 75: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

where izq.anio = der.anio; quit;

Estos 3 registros son el resultado de la intersección de ambas tablas. Como se puede comprobar el único elemento que necesitamos es la igualdad de campos en la cláusula WHERE. Al ser una consulta de selección no hemos tenido problemas con el nombre de los campos anio. Este tipo de cruces equivale al diagrama antes visto con la unión de tablas a través del paso DATA:

Con este tipo de uniones podemos realizar comparativas dentro de una misma tabla SAS, así si, por ejemplo, deseamos ver la diferencia entre los importes de distintos años para la tabla_izquierda realizaríamos la siguiente consulta: proc sql; title "Diferencias desde 2001"; select "Diferencia entre "||compress(put(izq1.anio,4.))||" y " ||compress(put(izq2.anio,4.)) as dif, izq1.importe1 - izq2.importe1 as dif_importes1 from tabla_izquierda as izq1, tabla_izquierda as izq2 where izq1.anio ne izq2.anio and izq1.anio>2001 and izq2.anio>2001; quit;

Page 76: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

Como vemos este cruce ha realizado un producto cartesiano más óptimo. Esta metodología de trabajo puede sernos muy útil a la hora de buscar relaciones dentro de una misma tabla. 8.3.2.2 Outer join Este tipo de uniones dan como resultado la combinación de los registros de dos tablas. Tres son los tipos de outers join:

• Left join: busca de la derecha los registros de la izquierda • Right join: busca de la izquierda los registros de la derecha • Full join: “todos contra todos”

La unión por la izquierda, el left join, es una consulta muy práctica para añadir variables a un conjunto de datos SAS. Con anterioridad vimos este esquema:

Con él simbolizábamos como añadimos variables a A de B cuyos registros que coincidan por un “campo clave” de ambas tablas. Siempre primaba la información de la tabla de la izquierda, la sintaxis la estudiamos con el siguiente ejemplo: proc sql; create table tabla_izquierda_derecha as select a.*, importe2 from tabla_izquierda as a left join tabla_derecha as b on a.anio = b.anio; quit; En el bloque FROM especificamos las tablas a unir y mediante ON identificamos el campo que realiza nuestra unión. El resultado serán todos los registros de tabla_izquierda a los que habremos añadido el campo importe2 de la tabla_derecha, abriendo la vista del explorador:

Obtenemos los 5 registros de tabla_izquierda y el valor de importe2 para 3 de ellos, los coincidentes por anio con tabla_derecha. La unión por la derecha, el right join, es análogo al left join, reutilizando el anterior diagrama:

Page 77: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

A la tabla B le añadimos las variables que coincidan de A. La sintaxis completamente análoga: proc sql; create table tabla_derecha_izquierda as select b.*, importe1 from tabla_izquierda as a right join tabla_derecha as b on a.anio = b.anio; quit; A la tabla_derecha le añadimos el campo importe1 de la tabla_izquierda para aquellos registros en los que coincida el campo anio:

En cuanto a la full join realiza una unión del total de registros. La sintaxis es similar pero los resultados son sorprendentes: proc sql; create table tabla_total as select a.*, b.* from tabla_izquierda as a full join tabla_derecha as b on a.anio = b.anio; quit;

Al existir el campo anio en selección (primero seleccionamos todo ‘*’ de la tabla_izquierda) pero los valores de anio de la tabla_derecha son missing porque los seleccionamos sobre la otra. Para evitar este problema podemos jugar con la instrucción CASE: proc sql; create table tabla_total as select case when missing(a.anio) then b.anio

Page 78: Introduccion a Sas

© 2007 Raúl Vaquerizo Introducción a SAS® | [email protected]

else a.anio end as anio, importe1, importe2 from tabla_izquierda as a full join tabla_derecha as b on a.anio = b.anio; quit;

8.3.3.3 Natural joins La natural join es un tipo de inner join para dos tablas en la que no necesitamos especificar el campo de cruce ya que la propia consulta unirá por las variables de las tablas con el mismo nombre y las mismas características, si no encuentra el campo de unión entonces nos devolverá un error. Si deseamos hacer la intersección de las tablas de nuestro ejemplo: proc sql; title "Ejemplo de Natural Join"; select * from tabla_izquierda natural join tabla_derecha ; quit; El resultado que devuelve es el mismo que el visto al estudiar las inner joins:

Este tipo de uniones nos pueden ahorrar escribir gran cantidad de código a la hora de cruzar dos tablas.