Procedimientos de agregación de datos en SAS

En el siguiente post mostramos con ejemplos los diferentes métodos de agregación de los que disponemos en el módulo BASE de SAS. Se incluye un script con ejemplos utilizando el procedimientos generalista 'proc sql' o bien procedimientos propios de agregación como 'proc means' o 'proc summary'

 

 

Agregados en SAS

 

En primer lugar mostramos el mismo agregado realizado en vía proc sql y vía proc summary o proc means:

 

proc sql:

proc sql;

create table agregado as

(select dimension1, dimension2, sum(indicador1), avg(indicador2), max(indicador3)

from detalle

group by dimension1, dimension2);

quit;

 

proc summary:

proc summary data=detalle nway;

   class dimension1 dimension2;

   var unidades;

   output out=agregado(drop=_type_ _freq_)

   sum(indicador1) = suma_indicador1 mean(indicador2) = media_ indicador2 max(indicador3) = max_indicador3 ;

run;

 

proc means:

proc means data=detalle noprint nway;

   class dimension1 dimension2;

   var unidades;

   output out=agregado(drop=_type_ _freq_)

   sum(indicador1) = suma_indicador1 mean(indicador2) = media_ indicador2 max(indicador3) = max_indicador3 ;

run;

 

Un resumen de equivalencias sería:

 

 



Funcionalidad


Procedimiento agregación


Proc sql


Tabla entrada


data=tabla_detalle


from tabla_detalle


Tabla salida


output out =tabla_agregado


create table tabla_agregado as


Indicadores de análisis


var indicador1 indicador2 …


Select sum(indicador1), mean(indicador2), ..


Variables de agregación


class indicador1, indicador2,…


group by dimension1, dimension2, …


Estadísticas a obtener


Especificadas en el procedimiento agregación


Especificadas en el proc sql

 

En los procedimientos de agregación tenemos la opción de dar la salida a último nivel de agregación o mostrando todos los niveles. Para quedarnos con el últimos nivel de agregación en base a la clave definida añadimos la claúsula nway. La clave de agregación queda definida en la claúsula class y en el output  indicamos la tabla de salida. Utilizamos la claúsula drop para eliminar las variables internas que genera el procedimiento y no queremos mostrar en la salida.  Finalmente definimos los valores estadísticos a obtener que en el caso del ejemplo son sum, mean y max y las variables donde los alojamos.  Ambos procedimientos dan la opción de obtener otros muchos valores estadísticos tales como:  rango (range), varianza(var), desviación estándar(stddev), etc..

 

En el procedimiento proc means se añade la claúsula noprint ya que por defecto da la salida en el output de SAS.  La principal diferencia entre proc summary y proc means es ésta de la salida y que proc means por defecto calcula valores estadísticos para todas las variables numéricas aunque no sean detalladas explícitamente en la salida.

 

Existen notables diferencias entre el uso e proc sql o de un procedimiento de agregación, siendo quizás la principal que el procedimiento de agregación obtiene agregados a todos los niveles y combinaciones posibles para las variables definidas en la clave, pudiendo manejar el nivel que queramos utilizando la variable interna _type_.

A continuación se incluye un script en el que partiendo de una tabla de detalle que se construye en el propio script de obtienen agregados a diferentes niveles utilizando tanto proc summary como proc means.

 

data ventas(drop = i j);

length oficina $100.;

oficina = 'Madrid';

do i = 1 to 10;

vendedor = compress('m_vendedor'||i);

       do j = 1 to 20;

       producto = compress('P'||j);

       unidades = round(ranuni(1)*20);

       output;

       end;

end;

oficina = 'Barcelona';

do i = 1 to 10;

vendedor = compress('b_vendedor'||i);

       do j = 1 to 20;

       producto = compress('P'||j);

       unidades = round(ranuni(1)*20);

       output;

       end;

end;

oficina = 'Valencia';

do i = 1 to 10;

vendedor = compress('v_vendedor'||i);

       do j = 1 to 20;

       producto = compress('P'||j);

       unidades = round(ranuni(1)*20);

       output;

       end;

end;

oficina = 'Lisboa';

do i = 1 to 10;

vendedor = compress('l_vendedor'||i);

       do j = 1 to 20;

       producto = compress('P'||j);

       unidades = round(ranuni(1)*20);

       output;

       end;

end;

run;

 

 

/* Agregado empleando proc sql */

/* Nivel.1 */

/* Agregado a nivel de variable oficina */

proc sql;

create table ag1_oficina as (

select oficina, sum(unidades) as sum1

from ventas

group by oficina);

quit;

 

proc summary data=ventas  NWAY ;

class oficina;

var unidades;

output out=ag1_oficina(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Agregado a nivel de variable vendedor */

proc sql;

create table ag1_vendedor as (

select vendedor, sum(unidades) as sum1

from ventas

group by vendedor);

quit;

 

proc summary data=ventas  NWAY ;

class vendedor;

var unidades;

output out=ag1_vendedor(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Agregado a nivel de variable producto */

proc sql;

create table ag1_producto as (

select producto, sum(unidades) as sum1

from ventas

group by producto);

quit;

 

proc summary data=ventas  NWAY ;

class producto;

var unidades;

output out=ag1_producto(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Nivel.2 */

/* Agregado a nivel de variables oficina y vendedor */

proc sql;

create table ag2_ofi_vend as (

select oficina, vendedor, sum(unidades) as sum2

from ventas

group by oficina, vendedor);

quit;

 

proc summary data=ventas  NWAY ;

class oficina vendedor;

var unidades;

output out=ag2_ofi_vend(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Agregado a nivel de variables oficina y producto */

proc sql;

create table ag2_ofi_prod as (

select oficina, producto, sum(unidades) as sum2

from ventas

group by oficina, producto);

quit;

 

proc summary data=ventas  NWAY ;

class oficina producto;

var unidades;

output out=ag2_ofi_prod(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Nivel.3 */

/* Agregado a nivel de variables oficina, vendedor y producto */

proc sql;

create table ag3_ofi_vend_prod as (

select oficina, vendedor, producto, sum(unidades) as sum3

from ventas

group by oficina, vendedor, producto);

quit;

 

proc summary data=ventas  NWAY ;

class oficina vendedor producto;

var unidades;

output out=ag3_ofi_vend_prod(drop = _type_ _freq_ ) sum = unidades;

run;

 

/* Empleamos proc summary para obtener todos los niveles de agregación y después

filtramos. Para obtener todos los niveles elimnamos clausul NWAY y controlamos en la

salida el nivel con la variable de sistema _type_ */

proc summary data=ventas ;

class oficina vendedor producto;

var unidades;

output out=ag_total(drop = _freq_ ) sum = unidades;

run;

 

/* A partir del agregado total y conociendo el valor de la variable _type_ para los diferentes

niveles, podemos sacar agregados a distintos niveles.

Por ejemplo, para obtener el agregado total por oficina, el agregado por oficina_vendedor

y el agregado a más bajo nivel sería */

data ag1_oficina (keep = oficina unidades)

ag2_ofi_vend (keep = oficina vendedor unidades)

ag3_ofi_vend_prod (keep = oficina vendedor producto unidades);

set ag_total;

if _type_ = 4 then output ag1_oficina;

if _type_ = 6 then output ag2_ofi_vend;

if _type_ = 7 then output ag3_ofi_vend_prod;

run;

  

/* Obtenemos el proc means equivalente al proc summary obtenido para el agregado

a más bajo nivel */

proc summary data=ventas  NWAY ;

class oficina vendedor producto;

var unidades;

output out=ag3_ofi_vend_prod(drop = _type_ _freq_ ) sum = unidades;

run;

 

proc means data=ventas noprint nway;

   class oficina vendedor  producto ;

   output out=ag3_ofi_vend_prod(drop=_type_ _freq_) sum = unidades ;

run;

 

sasybi.blogspot.com