Archivo de la etiqueta: array

Trucos SAS. Lista de variables missing

Duda que me plantearon ayer por la tarde. Dada una serie de variables determinar que registro tiene todas esas variables nulas. El truco que planteo puede servir para determinar incluso cuantos valores perdidos tiene esa lista de variables, ese truco me le reservo para otro día. El código lo acompaño con un ejemplo para que se pueda ejecutar y analizar su funcionamiento:

data aleatorio;
do i=1 to 20000;
aleat1=sqrt(rannor(45));
aleat2=sqrt(rannor(5));
aleat3=sqrt(rannor(4));
aleat4=sqrt(rannor(450));
aleat5=sqrt(rannor(40));
output;
end;
run;

data fila_nula;
set aleatorio;
nulo=0;
array varib(*) aleat1--aleat5;
do j=1 to dim(varib);
if not missing(varib(j)) then nulo=i;
end;
drop j;
if nulo=0;
run;

Muy sencillo el truco. Si se encuentra alguna variable que no es nula la variable nulo ya no toma valor 0. Espero que os sea de utilidad. Saludos.

Trucos SAS. Primer y último elemento de un array

Breve entrada sobre el uso de arrays en SAS. Dada una tabla SAS como esta con una variable mes1, mes2, … mesN:

arrays_sas.PNG

Necesitamos identificar el primer y el último elemento no nulo de un array y el número de elementos no nulos de ese array. Veamos el ejemplo:

data datos;
input id mes1 mes2 mes3 mes4 mes5 mes6;
datalines;
1 . . . . . .
2 162.18 88.41 919.62 891.25 837.73 163.14
3 . 790.52 160.03 . 60.31 343.30
4 . . 482.45 755.39 . .
5 265.17 963.53 . . 392.06 .
6 . 214.95 616.17 183.01 778.48 57.42
7 191.52 . 208.50 50.55 705.72 .
8 711.76 . . . 193.20 658.45
9 782.67 172.49 539.42 663.28 4.53 358.51
10 695.12 367.74 . 573.47 366.30 951.98
;
run;

Para este proceso creamos un array que recorreremos 2 veces, una hacia delante para identificar el primer elemento y otra a hacia atrás para identificar el último elemento:

data datos;
set datos;
array m(*) mes:;
*PRIMER ELEMENTO;
num=0;
do i = 1 to dim(m);
if m(i) ne . then do;
  primero=m(i);
  num=i;
  i=dim(m);
end;
end;
*ULTIMO ELEMENTO;
do i = dim(m) to 1 by -1;
if m(i) ne . then do;
  ultimo=m(i);
  num=i-num;
  i=1;
end;
end;
drop i;
num=num+1;
run;

Como hemos indicado el array se recorre dos veces, la primera vez de forma ascendente para buscar el primer elemento y la segunda de forma descendente para encontrar el último, la diferencia más uno es el número de elementos no nulos que tiene ese array. Ejemplo de uso de arrays en SAS. Saludos.

Trucos SAS. Operaciones con tablas de dimensiones con SAS

Algunos llaman a las tablas de dimensiones tablas de lookup, yo me niego. Con SAS ya hemos visto como crear cruces de tablas de dimensiones con tablas de hechos a través de formatos, bajo mi punto de vista el método más eficiente. Pero hoy quería traeros un ejemplo de cruce de tabla pequeña con tabla grande a través de arrays multidimensionales con SAS. Se trata de guardar los valores de la tabla “pequeña” en un array temporal multidimensional cuando leemos la tabla grande. Para ilustrar esta tarea he preparado un ejemplo:


data aleatorio;
do i =1 to 2000;
grupo = round(1+3*ranuni(4));
importe=ranuni(34)*grupo*1000;
output; end;
run;
proc summary data=aleatorio nway;
class grupo;
output out=medias (keep=grupo importe) mean(importe)=;
quit;

Generamos un conjunto de datos SAS aleatorio con una variable grupo y una variable importe, calculamos la media del importe por grupo y deseamos medir registro a registro la diferencia con respecto a la media del grupo. Para estos casos podemos trabajar con formatos o, por ejemplo, con macro variables:


data _null_;
set medias;
if grupo = 1 then call symput('med1',importe);
if grupo = 2 then call symput('med2',importe);
if grupo = 3 then call symput('med3',importe);
if grupo = 4 then call symput('med4',importe);
run;
data aleatorio;
set aleatorio;
if grupo = 1 then dif = importe/&med1.-1;
if grupo = 2 then dif = importe/&med2.-1;
if grupo = 3 then dif = importe/&med3.-1;
if grupo = 4 then dif = importe/&med4.-1;
run;

Estoy de acuerdo en que este código se puede hacer más eficiente pero sigue siendo algo engorroso. Bien, hoy quería plantearos otra forma de hacerlo a través de arrays multidimensionales. Planteo el código, lo ejecutáis y comentamos:

data aleatorio;
array med(4,2) _temporary_;
if _n_ = 1 then do i=1 to 4;
set medias;
med(i,2) = importe;
end;
set aleatorio;
dif = importe/med(grupo,2)-1;
run;

Se trata de recorrer nuestra tabla de dimensiones, en este caso la tabla con las medias y meter su contenido en un array temporal de 2 dimensiones que denomino med, este array tiene 4 filas y 2 columnas, la dimensión de nuestra tabla de dimensiones. Posteriormente leo la tabla de hechos y empleo el campo grupo para seleccionar el elemento del array que deseo. Es un código sencillo de replicar sobre todo si nuestras variables índices (en este caso la variable grupo) son números, en otro caso el código se complica ligeramente pero sigue siendo sencillo de interpretar. Estoy seguro de que este truco SAS puede resultaros útil (sobre todo a algún pésimo jugador de golf). Saludos.