En un
artículo anterior
, aprendimos a leer datos brutos externos. Hoy nos familiarizaremos con el operador SET, que lee conjuntos de datos SAS estándar (Conjunto de datos SAS), aprende a crear segmentos de datos, configura atributos persistentes y también aprende algunas funciones SAS útiles. Una vez más, intentaré presentar el material en el lenguaje más simple posible, usando tantos ejemplos como sea posible.
Digamos que los datos se almacenan en formato EXCEL en el directorio
C: \ workshop \ habrahabr . Importamos la hoja de cálculo, creamos un segmento a partir de ella, creamos nuevas columnas calculadas utilizando las funciones SAS y luego dividimos este conjunto de datos en dos.
Importe una hoja de cálculo y configure un filtro
El archivo de Excel se almacena en el directorio anterior y tiene este aspecto:
Fragmento de archivo:
Aplicamos el procedimiento
PROC IMPORT para convertir una hoja de cálculo en un conjunto de datos SAS:
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company replace; getnames=yes; run;
La opción
validvarname = V7 establece los nombres de campo correctos desde el punto de vista SAS: reemplaza todos los caracteres no válidos con guiones bajos. Las reglas para nombrar variables se pueden encontrar en la
Lección 1.Configuramos el filtro inmediatamente cuando leemos un archivo externo, por ejemplo, seleccionamos solo aquellas observaciones en las que no falta la fecha de finalización. Tenga en cuenta la sintaxis del parámetro where.
options validvarname=v7; proc import datafile="C:\workshop\habrahabr\company.xlsx" dbms=xlsx out=company (where=(End_Date not is missing)) replace; getnames=yes; run;
Consideremos en detalle los operadores de paso PROC IMPORT:
Archivo de datos : define la ruta completa y el nombre del archivo externo
Dbms : define el tipo de datos a importar.
Out : identifica el conjunto de datos de salida SAS con un nombre SAS de uno o dos niveles (nombre de biblioteca y nombre de conjunto de datos).
Reemplazar : sobrescribe un conjunto de datos SAS existente.
Getnames : indica si PROC IMPORT genera nombres de variables SAS a partir de los valores de datos en la primera línea del archivo externo de entrada.
Ejecute el paso PROC IMPORT y examine el REGISTRO:
Imprima el conjunto de datos SAS resultante:
proc print data=work.company noobs; run;
La salida del procedimiento PROC PRINT se muestra a continuación:
Fragmento:
También en SAS UE, puede usar la pestaña Resultados para ver el conjunto de datos SAS importado.
Lectura de conjuntos de datos SAS
La lectura del conjunto de datos SAS se implementa en el paso DATOS utilizando la instrucción
SET :
Considere la sintaxis general para la instrucción SET:
SET<SAS-data-set(s) <(data-set-options(s) )> > <options>
Si no especifica un conjunto de datos en la instrucción SET, lee las observaciones del último conjunto de datos SAS creado.
En la instrucción SET, puede especificar varios conjuntos de datos; en este caso, los conjuntos de datos SAS se agregarán uno debajo del otro (similar a UNION en SQL).
Además, en el paso DATOS, puede haber dos instrucciones SET, en cuyo caso las tablas están unidas por una columna común. Puede leer más sobre las dos declaraciones SET en
este artículo , por ejemplo.
El código más simple para crear una copia del conjunto de datos SAS es el siguiente:
data company1; set company; run;
Configurar un descriptor de conjunto de datos SAS
Puede examinar el descriptor del conjunto de datos SAS utilizando el procedimiento PROC CONTENTS (
consulte la Lección 2 ). En este tutorial, imprimiremos el componente descriptor utilizando el procedimiento
PROC DATASETS :
proc datasets library=work nolist; contents data=company order=varnum; quit;
Un fragmento de los resultados:
Establezca un formato constante para las variables Travel_Expenses y Budget:
data company; set company; format Travel_Expenses Budget dollar10.2; run;
Verifique los atributos de los conjuntos de datos SAS:
proc datasets library=work nolist; contents data=company order=varnum; quit;
Crear columnas calculadas
Todas las funciones de SAS pueden explorarse en las
Funciones de SAS 9.4 y Rutinas de LLAMADAS: Referencia, Quinta Edición .
Además, si no hay una función adecuada para realizar una tarea en particular, puede usar el procedimiento
PROC FCMP y crear su propia función.
En esta lección, exploraremos las tres funciones YRDIF, SUM y CATS.
Para calcular la diferencia en fechas en años, utilizaremos
la función YRDIF .
Permítame recordarle que una fecha en formato SAS es el número de días que comienzan el 1 de enero de 1960 (
vea la Lección 1 ). Sobre los datos presentados, necesitamos calcular el tiempo de ejecución:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); format Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Tenga en cuenta que al usar el formato 3.1 para la variable Lead_Time, redondeamos los valores calculados en el informe (!) A 1 decimal. ¡El operador de formato
no cambia el valor en el conjunto de datos SAS!
Un fragmento de los resultados:
A continuación, calculamos el costo del trabajo sin gastos de viaje:
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Un fragmento de los resultados:
Como parte de nuestra tarea, calculamos el costo del trabajo sin tener en cuenta los gastos de viaje sin utilizar la función. No hay valores faltantes en nuestra tabla, si una de las variables (Presupuesto o Gastos de viaje) tenía un valor perdido, el resultado fue "misión".
Por ejemplo:
Crear un conjunto de datos de prueba:
data test; input Budget Travel_Expenses; datalines; 12345 233 . 345 12543 . ;
Calcular la diferencia en variables Presupuesto Viajes_Gastos
data test; set test; value=Budget-Travel_Expenses; run;
El resultado de este paso:
Para obtener el resultado correcto, puede usar la función
SUMA .
Esta función pertenece a la categoría de funciones
estadísticas descriptivas . Las funciones estadísticas descriptivas
ignoran los valores faltantes.
Escribir código a través de SUM:
data test; set test; value=sum(Budget,-Travel_Expenses); run;
En este caso, el resultado del paso es el siguiente:
La tercera columna calculada es la dirección de correo electrónico del administrador. Se puede "ensamblar" desde las columnas Manager_FirstName, Manager_LastName y los valores
habr .com
Puede usar
la función CATS para combinar valores de texto en una línea.
data company1; set work.company; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Un fragmento de los resultados:
Examinemos el descriptor del conjunto de datos creado:
proc contents data=work.company1 varnum; run;
Fragmento de mango:
Preste atención a la longitud de la variable Correo electrónico: es de 200 bytes, esta es la longitud predeterminada que devuelve la función CATS. Si examinamos los atributos de las variables Manager_FirstName y Manager_LastName, entonces podemos asegurarnos de que 8 + 6 + la longitud de la cadena '@ habr.com' es suficiente para la variable Correo electrónico, es decir, otros 9 bytes, un total de 23. ¿Por qué debería prestar atención a esto? Todos los caracteres faltantes alcanzan espacios, lo que afecta el tamaño del conjunto de datos y afectará el rendimiento en grandes cantidades de datos.
Para establecer la longitud de la variable Correo electrónico explícitamente, debe usar el operador LENGTH:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; run;
Fragmento de mango
Cree una columna detallada basada en la variable Lead_Time, teniendo en cuenta las siguientes condiciones:
- Si el valor de la variable Lead_Time es inferior a 1, la columna Detalle tiene un valor inferior a 1 año.
- Si el valor de la variable Lead_Time está en el rango de 1 a 2, incluidos los bordes, entonces la columna Detalle tiene un valor de 1-2 años.
- Si el valor de la variable Lead_Time está en el rango de 2 a 3, excluyendo 2, entonces la columna Detalle tiene un valor de 2-3 años.
- Si el valor de la variable Lead_Time está en el rango de 3 a 4, excluyendo 3, entonces la columna Detalle tiene un valor de 3-4 años.
- Si el valor de la variable Lead_Time está en el rango de 4 a 5, excluyendo 4, entonces la columna Detalle tiene un valor de 4-5 años.
- En todos los demás casos, la columna Detalle tiene un valor superior a 5 años.
Puede crear una columna detallada de varias maneras, por ejemplo, la opción más simple y obvia es usar el procesamiento condicional. Se puede implementar utilizando los siguientes operadores:
- SI ENTONCES
- Si no
- SELECCIONAR CUANDO
Para grandes cantidades de datos, es más eficiente usar las dos últimas opciones.
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='4-5 years'; else detail='above 5 years'; run;
Agregue una condición que seleccione solo aquellas observaciones en las que el valor de la variable Detalle no sea igual a 'por encima de 5 años'. Cuando se utiliza where como filtro, se producirá un error de sintaxis:
La cláusula where no se usa para columnas calculadas. Para seleccionar las variables que necesitamos, necesitamos una declaración IF selectiva. Cancela la salida de la observación al conjunto de datos creado:
data company1; set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
Tenga en cuenta también que la instrucción selectiva IF requiere un operador aritmético. No podemos escribir, por ejemplo, así:
if detail contains 'above 5 years';
Se mostrará un error en el registro:
Configure el conjunto de datos SAS.
Las variables Manager_FirstName y Manager_LastName no deben estar presentes en el nuevo conjunto de datos SAS. Este requisito se implementa utilizando el parámetro DROP, y también se puede utilizar el operador DROP.
data company1 (drop=Manager_FirstName Manager_LastName); set work.company; length Email $23; Lead_Time=yrdif(Start_Date, End_Date, 'actual'); Cost=Budget-Travel_Expenses; Email=cats(Manager_FirstName, '.',Manager_LastName, '@habr.com'); format Cost Travel_Expenses Budget dollar10.2 Lead_Time 3.1; if Lead_Time<1 then detail='less than a year'; else if Lead_Time=>1 and Lead_Time<=2 then detail='1-2 years'; else if Lead_Time>2 and Lead_Time<=3 then detail='2-3 years'; else if Lead_Time>3 and Lead_Time<=4 then detail='3-4 years'; else if Lead_Time>4 and Lead_Time<=5 then detail='2-3 years'; else detail='above 5 years'; if detail ne 'above 5 years'; run;
Dividimos el conjunto de datos SAS creado en dos de acuerdo con la condición dada
En un paso de DATOS, puede crear múltiples conjuntos de datos SAS. Cree un conjunto de datos separado para cada país.
Para verificar qué valores hay en la columna País, por ejemplo, puede usar el procedimiento
PROC FREQ .
proc freq data=company1; table Country /nocum nopercent; run;
Este paso considera cuántas veces se produce un valor particular de la variable País en el conjunto de datos SAS especificado en el parámetro datos =.
El resultado de este paso será el siguiente:
Por lo tanto, crearemos dos conjuntos de datos en un paso de DATOS utilizando el operador OUTPUT y el procesamiento condicional:
data US AU; set work.company1; if Country='AU' then output AU; if Country='US' then output US; run;
Ejecute el código y vea LOG:
Esto es brevemente acerca de leer y configurar conjuntos de datos SAS. En el próximo artículo, le presentaremos la combinación de conjuntos de datos utilizando las declaraciones MERGE y SET.
Y como PS, les recordaré la estructura de nuestras lecciones SAS BASE:
Artículos que ya han sido publicados:
- Fundamentos de programación en BASE SAS. Lección 1
- Fundamentos de programación en BASE SAS. Lección 2. Acceso a datos
- Fundamentos de programación en BASE SAS. Lección 3. Lectura de archivos de texto.
- Acabas de aprender la cuarta lección.
En los siguientes artículos, me gustaría resaltar problemas tales como unir tablas en SAS Base (fusionar, configurar), procesamiento condicional, bucles, funciones SAS, crear formatos personalizados, SAS Macro, PROC SQL.

Estaré encantado de comentarios en los comentarios! ¿Qué otros temas te gustaría ver en los artículos?