Funciones de ventana, SAS y bases de datos

Hace unos meses padecí (eso sí, brevemente) un proyecto que consistía en la migración de cierto código en SAS (¡nos lo pasaron como un documento de 20 hojas de Word!) a otro lenguaje de programación.

Esencialmente, desde la nueva plataforma habrían de lanzarse consultas a cierta base de datos (cuando el código SAS permitiese resolver los cálculos como una consulta de SQL) y procesarse los resultados procedimentalmente desde el nuevo lenguaje de programación cuando SQL ,declarativo, no fuese suficiente. Surgió el problema de que el lenguaje procedimental era incapaz de procesar bloques tan grandes de información. Pero ésa es otra historia.

En esencia, lo que SQL era incapaz (¿lo era realmente? sigamos leyendo…) de procesar eran pasos data muy simples pero que contenían llamadas a la función lag. Esta función, en esencia, ordena a SAS en un paso data recordar el valor de cierta variable en la línea anterior para compararlo con el de la presente. Se usa principalmente para calcular incrementos cuando los datos están ordenados temporalmente.

Las nuevas especificaciones de SQL (la 2003 y la 2008) introdujeron y detallaron el uso de funciones de ventana. Las funciones de ventana son extensiones de las clásicas consultas con “group by”. Éstas últimas sólo permiten devolver una fila por cada nivel de agrupamiento. Las funciones de ventana permiten operar sobre el bloque completo que define un nivel y:

  • Devolver tantas filas como contiene el bloque
  • Devolver valores basados en la totalidad de las filas del bloque
  • Si los bloques, además, se ordenan, tener acceso al primer valor (o último, o enésimo) de cada bloque; o a la fila anterior (mediante lag).

Puede leerse más al respecto aquí y aquí.

Estoy seguro de que el uso de este tipo de extensiones ahorrará a muchos desarrolladores kilómetros de líneas de código y eones de tiempo de depuración.

2 comentarios en “Funciones de ventana, SAS y bases de datos

  1. Hola Raul,
    como bien dices existe la función Lag para poder desplazar los valores de una colunma tantas filas bajo como queramos (funcion lag4 correría la columna 4 filas abajo), pero tambien se puede usar más eficientemente
    un Do Until Loop que es más rapido y sirve para tal o mejor propósito en series temporales.Ejemplo:

    data test;
    input fecha Fondo $25. prima 8.6;
    format fecha mmddyy10.;
    cards;
    18111 Donpalomo_top50_ChinaUp 5.656
    18112 Donpalomo_top50_ChinaUp 5.691
    18110 Evaristo_euro_shares 4.233
    18111 Evaristo_euro_shares 4.237
    18112 Evaristo_euro_shares 4.311
    18113 Evaristo_euro_shares 4.318
    ;
    run;
    proc sort data=test; by fondo fecha; run;

    data evolucion_diaria;
    do until (fin);
    set test end=fin;
    by fondo fecha;
    if first.fondo then evol=.;
    else Evol=sum( prima , -prima_anterior) / prima_anterior;
    output;
    prima_anterior=prima;
    end;
    format evol percentn8.2;
    drop prima_anterior;
    run;

    Espero os sea de ayuda!

    Dani Fernández.
    Barcelona

  2. El problema está cuando tienes que hacer ese tipo de operaciones en otro lenguaje tipo PL/SQL, que creo que es a lo que se refiere Raúl. Hace unos meses tuve que utilizarlas y la verdad es que facilitan muchos cálculos y dan un buen resultado de rendimiento frente a otras alternativas como los cursores a pesar de que para mi problema en concreto el uso de estas funciones realizaba mas operaciones de las necesarias.

Deja un comentario

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