Objetos hash para ordenar tablas SAS

12 Nov

A partir de la versión 9.1 de SAS se incluyeron los objetos HASH. Hace tiempo ya demostramos su eficiencia en el cruce de tablas y hoy quería mostraros como se programa una ordenación empleando HASH. La verdad es que estoy saboreando mis últimos días con SAS v9.2, en breve volveré a una versión muy anterior. El codigo, en mi opinión, es muy sencillo y como es habitual tenemos ejemplo ilustrativo que comentaré a continuación:

*DATASET DE PRUEBA;
data uno;
array v(10);
do i=1 to 5000000;
importe=ranuni(mod(time(),1)*1000)*10000;
do j=1 to 5;
v(j)=ranuni(34)*100;
end;output;end;
run;
*REALIZAMOS LA ORDENACION CON HASH;
data _null_;
if 0 then set uno;
declare hash obj (dataset:'uno',hashexp:20,ordered:'a') ;
obj.definekey ('importe');
obj.definedata(all:'YES');
obj.definedone () ;
obj.output(dataset:'dos');
stop;
run;

Importante: sólo funciona en versiónes posteriores a la 9.1

Empleamos data _null_ y una sentencia condicional para que lea el dataset que deseamos ordenar. Con DECLARE creamos el objeto hash OBJ del dataset uno e indicamos que ha de estar ordenado ‘a’scendentemente, podríamos ordenar ‘d’escendentemente. Al parámetro HASHEXP le vamos a llamar exponente hash y determina el número de cubos en el que vamos a repartir la tabla hash, en este caso 2**8=256 cubos, es un parámetro muy importante para que este proceso sea eficiente. Definimos la KEY con DEFINEKEY y así indicamos el campo por el que realizaremos la ordenación, pueden aparecer más variables. DEFINEDATA indica las variables que se recogen en el objeto en este caso empleamos all:’YES’ para quedarnos con todas, podría funcionar como un keep pero necesitamos poner todas las variables entrecomilladas y separadas por comas, así que recomiendo usar esta sintaxis. Finalizamos las deficinciones con DEFINEDONE(). Por último en OUTPUT indicamos el conjunto de datos SAS que se genera, podría ser el mismo que se lee, no es un problema.

Estas 4 líneas sencillas de recordar son una forma eficiente de ordenar conjuntos de datos SAS. Pero hay que analizar cuánto es de eficiente. Como ya he comentado, en breve volveré a versiones anteriores de SAS y no sé si podré seguir desarrollando pruebas con objetos hash pero es muy importante estudiar el consumo de memoria y el consumo de espacio y por supuesto compararlo con el PROC SORT. Además tengo que elaborar unas reglas de uso del parámetro hashexp, fundamental para el algoritmo y sobre todo fundamental para que las ordenaciones sean lo más eficientes posibles. ¡Anda que no tengo trabajo! Y pocos días con 9.2

Lo que si puedo hacer es adelantaros algunas conclusiones. Hash consume más memoria, menos espacio y tarda menos pero hay que analizar ese consumo de memoria con mucho detenimiento. Saludos.

4 respuestas a «Objetos hash para ordenar tablas SAS»

  1. Me gustaría saber si este código fincionaría en una versión 9.1.3 servipack3:
    No realiza la ordenación que yo esperaba.

    157 data _NULL_;
    158 if 0 then set rar.basemoto;
    159 declare hash obj (dataset:’rar.basemoto’,hashexp:5, ordered:’a’) ;
    160 obj.definekey (‘F55_COD_CBANCO’,
    161 ‘F55_COD_COFICI’);
    162 obj.definedata (all:’YES’);
    163 obj.definedone ();
    164 obj.output(dataset:’basemoto_2′);
    165 stop;
    166 run;

    NOTE: There were 12200080 observations read from the data set RAR.BASEMOTO.
    NOTE: The data set WORK.BASEMOTO_2 has 3586 observations and 426 variables.
    NOTE: DATA statement used (Total process time):
    real time 4:12.00
    cpu time 1:42.04

  2. Hola Iván, creo que no te va a funcionar con la versión de SAS con la que trabajas. Yo no dispongo de una versión de SAS parecida. Voy a buscarme una para confirmarte esto que te comento. Saludos.

  3. Hola buen día.

    Quisiera saber su en la variable definekey podriamos hacer algún filtro es decir, tengo una variable llamada «menor» y enta variable contiene 4 posibles valores, a, b, c y d.

    ¿Es posible que dentro de definekey pongamos menor=a?

    Espero me puedan ayudar.

    Saludos desde México.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *