SAS9

Automatizar el procesamiento de múltiples tablas en una carpeta

Simon 8 vues

Un desafío frecuente para los analistas de SAS© es tener que repetir una operación (como un MERGE para agregar una columna) en docenas de tablas ubicadas en el mismo directorio. Escribir 50 veces la llamada a la macro %jig(name=AB);, %jig(name=AC);... es tedioso y propenso a errores.

¿Cómo hacer para que SAS© "explore" la carpeta y aplique la macro automáticamente a cada archivo? Aquí está el método elegante propuesto por WeAreCas, utilizando los metadatos de SAS©.

1. La Estrategia: Diccionarios y CALL EXECUTE

El enfoque se basa en dos pilares de la programación dinámica de SAS©:

  1. Recuperar la lista de nombres: Usar las vistas de diccionario (SASHELP.VTABLE) para listar automáticamente todo lo que se encuentra en una biblioteca.

  2. Generar el código dinámicamente: Usar la instrucción CALL EXECUTE en un Data Step para ejecutar la macro para cada nombre encontrado.

2. El Código Paso a Paso

Paso 0: Definir la Macro de procesamiento

Este es el código que el usuario quiere ejecutar para una sola tabla.

1%macro jig(name);
2 DATA datdir.NEW_&name;
3 /* Attention : les deux tables doivent être triées par ID au préalable */
4 MERGE excelsheetdata datdir.&name;
5 BY ID;
6 RUN;
7%mend jig;

Paso 1: Listar las tablas objetivo (PROC SQL)

En lugar de escribir los nombres manualmente, le preguntamos a SAS©: "Dame la lista de todas las tablas no vacías presentes en la biblioteca 'DATDIR'."

1
 
1PROC SQL;
2 create TABLE liste_tables as
3 select memname
4 from sashelp.vtable
5 where LIBNAME='DATDIR' /* Nom de la lib en MAJUSCULES */
6 and memname like 'DATA_%'; /* Filtre optionnel si besoin */
7QUIT;
Nota: SASHELP.VTABLE contiene los metadatos de todas las tablas activas.
Note :
Paso 2: La automatización (CALL EXECUTE)
Aquí es donde ocurre la magia. Recorremos la lista creada en el paso 1, y para cada línea, construimos un comando textual que llama a la macro.
1DATA _null_;
2 SET liste_tables;
3
4 /* Construction de la chaîne : '%jig(TABLE_1)' */
5 commande = '%jig(' || strip(memname) || ')';
6
7 /* Exécution immédiate de cette commande */
8 call execute(commande);
9RUN;

3. Análisis de la sintaxis CALL EXECUTE

En la solución propuesta por WeAreCas, notará una sintaxis un tanto compleja:

call execute( '%nrstr( %%)' !! 'jig(' !! memname !! ') ' );

¿Por qué %nrstr(%%)?

  • CALL EXECUTE resuelve las macros durante la ejecución del Data Step.

  • A veces, queremos retrasar esta ejecución o proteger ciertos caracteres especiales.

  • En la mayoría de los casos simples (como aquí), call execute('%jig(' || memname || ')'); es suficiente.

  • La adición de %nrstr a menudo sirve para evitar que SAS© intente resolver la macro demasiado pronto si contiene variables macro conflictivas.

Resumen del Método

MétodoVentajaInconveniente
ManualFácil de entender.Largo, repetitivo, riesgo de olvido.
Wildcards (ej: DATA_: )Rápido para un SET simple.No funciona para un MERGE complejo.
Diccionarios + Call ExecuteCompletamente automático, flexible.Requiere conocimiento de SQL y meta-programación.

El consejo técnico: No olvide que para que un MERGE funcione, todas sus tablas (¡las 50!) deben estar previamente ordenadas por la variable clave (ID). Si este no es el caso, deberá agregar un PROC SORT dentro de su macro %jig.