Uno de los desafíos clásicos en la manipulación de datos (Data Management) es cruzar dos tablas no por una igualdad estricta, sino por una ventana de tiempo relativa.
El escenario típico es el siguiente: usted tiene una tabla de referencia que contiene fechas de eventos clave (ej: fecha de balance, fecha de campaña de marketing) y una segunda tabla que contiene un historial de transacciones. El objetivo es recuperar, para cada evento clave, todas las transacciones que tuvieron lugar en los 12 meses anteriores.
A diferencia de una fusión clásica (MERGE) que exige claves idénticas, este problema requiere una unión de desigualdad.
El Escenario
Tomemos dos conjuntos de datos para ilustrar la problemática:
Tabla de Referencia (HAVE_BASE) : Contiene las empresas y sus fechas pivote. Tenga en cuenta que la empresa 'A' aparece dos veces con dos fechas diferentes.
Tabla de Eventos (HAVE_EVENT) : Contiene el historial de resultados financieros (EPS) por empresa en diversas fechas.
El objetivo es extraer las líneas de la tabla EVENT donde la fecha está comprendida entre [Fecha de Referencia - 12 meses] y [Fecha de Referencia].
Preparación de los datos
Dado que las fechas a menudo se importan como cadenas de caracteres (ej: "199701"), el primer paso crítico es convertirlas a fechas SAS© numéricas verdaderas para permitir los cálculos aritméticos.
¿Por qué el paso DATA (Merge) no es adecuado?
Un intento intuitivo sería utilizar el paso DATA con una instrucción MERGE. Sin embargo, MERGE empareja las líneas secuencialmente basándose en una igualdad estricta de las variables BY.
Si intenta filtrar con condiciones como if date >= intnx('month', date_b, -12), esto a menudo fallará en los casos "Muchos a Muchos" (varias fechas de referencia para la misma empresa) porque el puntero de lectura de SAS© no puede "retroceder" para volver a probar las líneas históricas para la segunda fecha de referencia.
La Solución Óptima: PROC SQL
El lenguaje SQL es perfecto para este caso porque genera un producto cartesiano sobre la clave de unión (company), luego filtra los resultados según la ventana de tiempo. Esto permite que una misma línea de evento se asocie a varias fechas de referencia si las ventanas se superponen.
El Código
La función clave aquí es INTNX, que permite desplazar una fecha un número preciso de intervalos (aquí, -12 meses).
Análisis de la cláusula WHERE
base.company = evt.company : Indispensable. Sin esto, compararía las fechas de la empresa A con las de la empresa B.
intnx('month', base.date, -12) : Calcula el límite inferior de la ventana (la fecha situada exactamente 12 meses antes de la fecha de referencia).
El operador <= : El encuadre Límite_Inf <= Fecha_Evt <= Límite_Sup es el método más eficaz y legible para definir el intervalo.
Resultado e Interpretación
Si la empresa 'A' tiene una fecha de referencia en Enero de 1997 y otra en Junio de 1996 :
El SQL tratará primero Enero de 1997 : Buscará todos los eventos de 'A' entre Ene 96 y Ene 97.
Luego tratará Junio de 1996 : Buscará todos los eventos de 'A' entre Jun 95 y Jun 96.
Si un evento tiene lugar en Mayo de 1996, aparecerá dos veces en el resultado final (una vez asociado a la referencia del 97, otra vez a la del 96), lo cual es el comportamiento correcto esperado para un análisis de este tipo.
Para cruzar datos en intervalos de tiempo (ventanas deslizantes):
Priorice PROC SQL en el paso DATA.
Asegúrese de que sus fechas estén en formato numérico.
Utilice INTNX para calcular dinámicamente los límites de su ventana de tiempo en la cláusula WHERE.