Manejo de bases¶
En esta sección se presentan temas más profundos acerca del procesamiento de datos. Se explorarán distintas formas de manejar bases mediante uso de variables, seleccionar observaciones así como el uso de ciclos y arreglos que nos permitan tener un mayor control de la información que se tenga.
Primero se verá la forma de crear variables con el fin de realizar cálculos posteriores, estas variables pueden ser usadas incluso para crear varios datasets, crear contadores o acumuladores, entre otras. También se conocerán técnicas de selección de observaciones con el fin de manipular mejor las bases.
Después se explorará un poco el tema del ordenamiento con el fin de crear ya sea grupos o realizar otras operciones como uniones, transposiciones entre otras.
Antes de continuar con temas mas complejos, es importante comprender de forma general el funcionamiento del paso DATA.
Para una explicación más detallada consulte Cómo funciona el paso DATA.
El paso DATA tiene dos fases:
- Fase de compilación
- Fase de ejecución
A continuación se describir´n de forma breve estas fases.
Durante la fase de compilación, SAS revisa la sintaxis y si es correcta, se manda a código máquina en dondese procesa el código y se generan los siguientes objetos:
- Memoria de entrada. Es un lugar en la memoria donde SAS lee registros de un archivo de texto cuando el programa se ejecute.
- Vector de datos del programa. Es un lugar en la memoria donde SAS construye un conjunto de datos, una observación a la vez.
- Porción descriptora. Es la información general del dataset como el nombre de la base y los atributos de las variables a crear.
La memoria de entrada solo aplica en el caso en que se lean archivos externos. En este caso, los datos se leen de la memoria de entrada al vector de datos del programa.
El vector de datos del programa (VDP) es importante porque en éste se realizarían los cálculos de las sentencias de SAS o funciones. Contiene el nombre de todas las variables declaradas o inicializadas. Es como un paso intermedio entre lo que se lee y calcula con lo que se se escribe al dataset. Al inicio de cada iteración los valores en el VDP son iniciados con valor missing y son llenados según lea o ejecuten sentencias.
Durante la fase de compilación tambien se crean dos variables auxiliares en el VDP que no se escribirán en el dataset: _N_
y _ERROR_
. La primera cuenta el número de veces que el paso DATA itera y la segunda registra si hubo algún problema en la fase de ejecución.
Una vez concluída esta etapa, se procede a la siguiente fase.
En la fase de ejecución se realizan las siguientes acciones:
- Se leen las observaciones del VDP.
- Se ejecutan las sentencias (cálculo de variables).
- Se escriben al dataset.
- La variables en el VDP son reiniciadas y se colocan valores missing.
Debido a que es un procesos repetitivo, SAS realiza los pasos mencionados tantas veces como observaciones haya en el archivo externo o dataset leído.
El proceso termina cuando ya no hay registros que leer y en ese momento el dataset es cerrado y se concluye el paso DATA.
Creando variables¶
Hasta ahora solo conocíamos las sentencias ATTRIB
, LENGTH
y FORMAT
para declarar o iniciar variables. Otra forma de crearlas es mediante la asignación de variables de la siguiente forma:
variable = expresión sas;
Esta sentencia se conoce como sentencias de asignación. Su función es evaluar y almacenar el resultado en alguna variable que está al lado izquierdo del signo =
.
Una forma muy común de crear variables es mediante el uso de operadores matemáticos. La siguiente tabla muestra algunos de los operadores aritméticos en SAS. Para una referencia consulte Operadores SAS en expresiones y Funciones SAS en expresiones.
Símbolo | Descripción | Ejemplo |
---|---|---|
+ |
Adición | fecha + 1 |
- |
Sustracción | fecha - 7 |
* |
Multiplicación | height * 2.54 |
/ |
División | suma / total |
** |
Exponenciación | metros ** 2 |
Considere las siguientes sentencias:
1 2 3 4 5 |
|
En esas sentencias se han creado las variables simplemente asignando un valor o una expresión SAS.
Las primeras tres sentencias crearían variables de tipo numérico; la expresión '10Jun20'd
es interpretada por sas como un valor numérico.
La cuarta sentencia realiza una multiplicación de una variable por una constante.
Finalmente, la quinta aplica una función a una variable de tipo caracter que extraerá los 3 primeros caracteres de una cadena. Para conocer un poco más vea la sección.
A continuación se presentan algunas variables que serán muy útiles.
Variables acumuladoras y contadoras¶
En SAS es posible crear una variable que sume o vaya acumulando.
Considere la siguiente tabla donde se representan la información de los empleados de una compañía. Se desea obtener un acumulado de las ventas de los empleados y un contador para tener en cuenta el número de empleados.
El siguiente código muestra la forma de crear el acumulador y el contador de forma muy básica.
1 2 3 4 5 |
|
La tercer línea guarda el número de veces que se ha iterado, es decir el número de registros leídos. Debido a que la variable _N_
es temporal y no se escribe en el dataset, se guarda en la variable contador.
En la cuarta se muestra cómo acumular en la variable salario_acum, en cada iteración se le suma la variable salary a la variable salario_acum. Esta sentencia es conocida como sentencia SUM.
Cuidado con el operador +
Se debe tener cuidado al usar el operador +
debido a que si alguno de los operandos tiene un valor missing, el resultado sería missing. Se recomienda usar la función SUM para evitar esos imprevistos.
Si se hubiese definido salario_acum = salario_acum + salary
en la línea 4, el resultado en cada observacion nos resultaría un valor missing. Como se mencionó previamente, durante la fase de compilación los valores en el VDP se reinician a valor missing causando que el resultado en dicha expresión sea missing.
Para evitar que eso ocurra, se puede usar la sentencia RETAIN
con el fin de que SAS conserve el valor en cada iteración.
1 2 3 4 5 |
|
En la línea 3 se pide que SAS retenga la variable salario_acum2 en cada iteración y que su valor inicial sea 0. De esta manera se podría sumar de manera normal. Consulte la sentencia RETAIN para más información.
Funciones y llamadas a rutinas¶
Ya habíamos mencionado que las funciones podían usarse para crear variables, sin embargo ahora se profundizará un poco más en su uso.
Las funciones permiten realizar cálculos y operaciones en ocasiones muy complejas, éstas pueden requerir de cierta información o argumentos con el fin de traer el resultado. Generalmente son almacenadas en variables, aunque pudieran usarse como una expresión en una sentencia WHERE
o IF
. Su sintaxis es la siguiente:
<variable => funcion(<argumento1,argumento2,…,argumenton>);
Las llamadas a rutinas, en cambio en lugar de arrojar un resultado, realizan una acción u operacion. Su sintaxis es la siguiente:
CALL rutina(<argumento1,argumento2,…,argumenton>);
Para más información acerca de las llamadas a rutinas y funciones consulte Funciones SAS y rutinas.
Filtrado de datos¶
En ocasiones, se tiene una basta cantidad de datos y solo nos interesa un subconjunto de estos. Para eso se pueden elegir observaciones de un dataset con la sentencia WHERE
.
WHERE vs IF
No debe confundirse la sentencia WHERE
con IF
. La sentencia IF
trabaja con observaciones después de ser leídas en el VDP, mietras que WHERE
selecciona las observaciones antes de pasar al VDP.
La sintaxis es la siguiente:
WHERE expresión;
donde expresión es una condición a evaluar, vea la sección selección de observaciones para una referencia de los operadores lógicos y booleanos. La siguiente tabla muestra expresiones válidas para la sentencia WHERE
Operador | Descripción | Ejemplo |
---|---|---|
BETWEEN - AND |
Un rango inclusivo | WHERE age BETWEEN 12 AND 15; |
? o CONTAINS |
Una cadena de caracteres | WHERE name ? "Ja"; |
IS NULL o IS MISSING |
Valores faltantes | WHERE volumen IS NULL; |
LIKE |
Combinación de patrones | WHERE name LIKE "J%"; |
=* |
Suena como (Sólo palabras en inglés) | WHERE name =* "jeims"; |
SAME - AND |
Agrega cláusulas a una sentencia WHERE existente |
WHERE sex = "F"; WHERE SAME AND age >= 13; |
En el siguiente ejemplo se muestra el filtrado usando la sentencia WHERE
usando los datos de covid para tener sólo la información de México.
1 2 3 4 |
|
El log muestra el siguiente mensaje:
NOTE: There were 609 observations read from the data set WORK.COVID.
WHERE iso_code=’MEX’
Si se hubiese usado la sentencia IF
en lugar de WHERE
el resultado hubiera sido el siguiente:
NOTE: There were 113406 observations read from the data set WORK.COVID.
NOTE: The data set WORK.MEXICO has 609 observations and 60 variables.
El ejemplo anterior muestra las diferencias entre las sentencias IF
y WHERE
.
WHERE
como opción de dataset
Es posible usar la opción WHERE =
para filtrar observaciones para un dataset especificado, esto es útil cuando se leen más de un dataset. Vea la documentación para más información.
Sentencias condicionales¶
Anteriormente se había usado la sentencia IF
para seleccionar variables, ahora se usará en conjunto con la palabra THEN
con el fin de que realice una acción. Esta sentencia se conoce como sentencia IF-ELSE.
La sintaxis es la siguiente:
IF expresión THEN acción1; ELSE acción2;
El siguiente ejemplo muestra cómo crear una variable a partir de ciertos valores.
1 2 3 4 5 6 |
|
Note que la sentencia IF-ELSE
solo permite una acción a la vez. Para realizar más de una acción se debe usar el bloque DO
. Consulte la documentación para más información.
1 2 3 4 5 6 7 8 9 |
|
Estas sentencias pueden anidarse para formar sentencias más complejas, por ejemplo.
1 2 3 4 5 6 7 |
|
Cuidado con las estructuras anidadas
Se debe tener cuidado al usar sentencias anidadas ya que deben ser cerradas correctamente. De no ser así, se pueden cometer errores.
Otra forma de crear sentencias condicionales es mediante el uso de la sentencia SELECT
. Consulte la ayuda para más información.
1 2 3 4 5 6 7 8 9 |
|
No confundirse
Esta sentencia no debe confundirse con la sentencia SELECT de SQL. Para hacer algo similar en SQL, revise este ejemplo.
Ciclos¶
Al igual que otros lenguajes de programación SAS dispone de sentencias de ciclo repetitivos. Estas sentencias son útiles para simulación de datos o para ingreso de datos repetitivos.
DO iterativo¶
Es el equivalente al FOR de algunos programas
La sintaxis es la siguiente:
DO variable-índice=lista;
sentencias sas;
END;
donde lista puede ser un rango de valores consecutivos (indicando inicio, fin e incremento) o una lista de valores. Consulte la documentación para una mayor referencia.
El siguiente ejemplo muestra su uso
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
El dataset anterior lee los datos señalados por la sentencia INPUT
. En la primer iteración (es decir,cuando lee “azul”) entra al ciclo DO y se escribe en el VDP el primer valor de la secuencia (i). La instrucción OUTPUT
indica que se debe escribir ese valor al DATASET. Esto se repite para los valores restantes (3 y 5). Note que aún estamos en la primer iteración (es decir _N_ = 1
).
Cuando se terminan los valores del ciclo DO, se lee la segunda observación del DATALINES y se repite lo mismo.
Esta estructura también es útil para leer datos consecutivos y hacer secuencias, por ejemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Note que derante la primer iteración (_N_ = 1
) se inicia el ciclo DO
con valores del 1 al 4. Una vez dentro del ciclo, SAS empezará a leer los 4 primeros valores del DATALINES
y los escribirá al dataset. Esto se repetirá hasta que ya no haya observaciones por leer.
DO CONTINUE¶
SAS tiene una sentencia especial que permite, dentro de un ciclo, saltar al siguiente valor de la variable índice. Esto puede ser útil para prevenir que otras sentencias se ejecuten.
El siguiente ejemplo muestra su uso.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
El código anterior evita que en el dataset se ingresen los colores blanco o negro, ya que al cumplirse la condición no se ejecuta la sentencia OUTPUT;
.
Consulte la ayuda de SAS para más información acerca de la sentencia CONTINUE
.
DO LEAVE¶
A diferencia de la sentencia CONTINUE
, la sentencia LEAVE
permite salir del ciclo DO
.
El siguiente ejemplo muestra el uso de la sentencia LEAVE
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
En este caso, cuando se cumple la condición, sale del ciclo DO y esto implica que se lea la siguiente línea por lo que no se toma en cuenta los valores que hay en las líneas 11 y 14.
Consulte la sentencia LEAVE para más información.
DO WHILE¶
La sentencia DO WHILE
es un bloque de instrucciones que se ejecuta siempre que se esté cumpliendo la condición, dicha condición debe cumplirse forzosamente antes de entrar al ciclo, de otra forma no se ejecutará.
El siguiente ejemplo muestra el uso de la estructura DO WHILE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
En el código anterior, se define un contador con el valor de 1 y una variable de paro con el valor de 100. Al entrar al ciclo, se leen las líneas con la sentencia INPUT
. Cuando el color es blanco o negro, se modifica el criterio de alto con el fin de salir del ciclo y con ello se pasa a la segunda iteración, reiniciándose tanto el contador (1) como el criterio de alto (100).
Condición de alto
Siempre es importante definir una expresión o condición de alto, de otra forma, se entraría en un ciclo infinito.
Para conocer más vea la ayuda de SAS sobre esta sentencia.
DO UNTIL¶
A diferencia de las instrucciones anteriores, la sentencia DO UNTIL
asegura que al menos se ejecuta una vez.
La expresión se evalúa al final de las sentencias del bloque. Si la expresión es verdadera, el ciclo ya no itera.
Usando el mismo código que en la sección anterior, se muestran los resultados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Note que en la primer iteración se entra al ciclo y se escriben los valores al dataset. En el segundo valor leído (negro) se cumple la condición pero ya ha cambiado el valor de las variables contador y alto a cero y se salta a la siguiente iteración.
Con la nueva iteración se reinician los valores iniciales hasta que se cumpla la condición.
Para más información vea la sección DO UNTIL.
Arreglos¶
Supóngase que se desea tener información de ventas acomodada en columnas, donde cada una represente un trimestre.
Una forma de introducir esta información es mediante el uso de arreglos o arrays, los arreglos nos ayudan a crear variables de forma fácil ya que sus elementos serán usados como nombres de variables. El siguiente ejemplo muestra cómo definir un arreglo.
1 2 3 4 5 6 7 8 9 10 11 |
|
En la línea 2 se define un arreglo de nombre Tri cuyos elementos son T1, T2, T3 y T4, estos elementos son usados en la línea 4 en la sentencia INPUT
.
No confundir con otros lenguajes
A pesar de que tienen un nombre idéntico, los arreglos no son iguales a los objetos de otros lenguajes de programación.
Los arreglos tambien son útiles para crear variables de forma iterativa y pueden ser usadas dentro de un ciclo.
1 2 3 4 5 6 7 8 9 |
|
En el ejemplo anterior,en la línea 2 se define un vector con 3 elementos y sus valores iniciales son cero. Se ha usado un doble ciclo y el valor calculado en la línea 5 se guarda en la variable correspondiente de acuerdo a los índices i
y j
.
El resultado se muestra a continuación
Para conocer más acerca del uso de arreglos visite la ayuda de SAS sobre arreglos.
Manipulación y transformación de bases¶
Cuando se tiene la información almacenada, en ocasiones es necesario modificarla según las necesidades, por ejemplo para segmentarla, agruparla o realizar ciertas operaciones para análisis posteriores.
En esta sección se estudiarán las formas de transformar las bases de datos, tales como ordenar una base, transponerla, unir una base a otras y modificar una base.
Ordenando una base¶
SAS posee un procedimiento especializado en ordenar bases por una o más variables. El procedimiento SORT, permite entre otras cosas, ordenar una base por una o más variables ya sea numérica o de tipo caracter.
La sintaxis básica es la siguiente:
PROC SORT <collating-sequence-option> <other options>;
BY <DESCENDING> variable-1 <<DESCENDING> variable-2 …>;
Consulte secuencia de cotejado para conocer más acerca de cómo SAS ordena las variables.
Por ejemplo, supóngase que se tiene la tabla calificaciones y se desea ordenar la base por el nombre y grupo del estudiante.
Nombre | Grupo | Puntaje |
---|---|---|
ANGÉLICA | A | 10 |
BRENDA | A | 9 |
MARCO | B | 8 |
LILIANA | B | 8 |
FABIÁN | C | 9 |
MAURICIO | C | 7 |
ÁLVARO | A | 8 |
ÓSCAR | B | 9 |
BELÉN | C | 10 |
1 2 3 |
|
El resultado del código anterior se presenta a continucación.
Sin embargo se puede observar que los nombres no están ordenados correctamente, debido a que los nombres acentuados están al final.
Para solucionar eso, se puede usar otra opción de secuencia de cotejado para que se ordene de manera correcta, en este caso se usará la opción SORTSEQ = LINGUISTIC
para que SAS ordene los nombres correctamente.
1 2 3 |
|
Ordenamiento en español
Al usar la opción de secuencia de cotejado SORTSEQ = SPANISH
, las letras con acento se ordenarían primero y no seguirían un órden lógico.
El resultado se presenta a continuación.
Eliminación de datos duplicados¶
Cuando se tiene información en donde cada individuo posee un identificador o clave única, es importante quitar duplicados con el fin de evitar información redundate.
El procedimiento SORT, no solo ordena, sino que también permite eliminar datos duplicados.
Considere esta tabla con información de clientes de una compañia
Number | GivenName | Surname | Birthday | Age | Occupation |
---|---|---|---|---|---|
1 | Ezio | Vanegas | 04/06/1942 | 79 | Labor economist |
2 | Katharina | Reséndez | 12/08/1967 | 53 | Support clerk |
3 | Tamara | Monroy | 02/01/1948 | 73 | Analytical chemist |
4 | Dunstano | Armendáriz | 05/07/1985 | 36 | Specification inspector |
5 | Baldo | Ayala | 04/10/1952 | 69 | Sportscaster |
6 | Adrián | Rosales | 8/28/1992 | 29 | Gas appliance repairer |
7 | Helvia | Viera | 12/16/1994 | 26 | Hostler |
8 | Astor | Cortez | 12/04/1965 | 55 | Adult secondary education teacher |
9 | Giusto | Carvajal | 5/27/1986 | 35 | Fish and game warden |
10 | Baal | Alcalá | 1/15/1961 | 60 | Conciliator |
1 | Ezio | Vanegas | 04/06/1942 | 79 | Labor economist |
4 | Dunstano | Armendáriz | 05/07/1985 | 36 | Specification inspector |
5 | Baldo | Ayala | 04/10/1952 | 69 | Sportscaster |
10 | Baal | Alcalá | 1/15/1961 | 60 | Conciliator |
10 | Baal | Alcalá | 1/15/1961 | 60 | Conciliator |
El siguiente ejemplo muestra como desduplicar los clientes de la tabla anterior y la información de los clientes duplicados se guardará en un tabla para un análisis posterior.
1 2 3 |
|
La tabla ordenada y sin duplicados se muestra a continuación.
Por otro lado, la tabla con los clientes duplicados se ha guardo y podría servir para un otro análisis del por qué hay información duplicada.