Data Step

Cómo recuperar el valor de una variable cuyo nombre está almacenado en otra columna?

Simon 4 vues

Es frecuente que, al manipular datos complejos en SAS©, nos encontremos con un problema de referencia dinámica. Imagine un conjunto de datos donde una columna no contiene un dato bruto, sino el nombre de otra variable de la tabla cuyo valor queremos extraer.

El Escenario

Tomemos el ejemplo de un dataset que contiene estadísticas (FIELD_AVG, FIELD_SUM) y una columna de control llamada REQ_STAT.

Esta columna REQ_STAT indica qué estadística debe conservarse para la fila actual.

  • Si REQ_STAT es "FIELD_AVG", queremos el valor numérico de la columna FIELD_AVG.

  • Si REQ_STAT es "FIELD_SUM", queremos el valor de FIELD_SUM.

El objetivo es crear una nueva variable, FIELD_STAT, que contenga este valor final.

La falsa buena idea: SYMPUT y SYMGET

El primer reflejo de muchos programadores es intentar usar las funcionalidades de macrovariables en tiempo de ejecución (run time) a través de CALL SYMPUT y SYMGET.

El código a menudo se ve así:

1DATA target_ds;
2 SET source_ds;
3 /* Tentative d'assigner le nom de la variable à une macro */
4 CALL SYMPUT('field_val', req_stat);
5 /* Tentative de récupérer la valeur */
6 field_stat = SYMGET('field_val');
7RUN;
¿Por qué esto no funciona? El resultado de este código no será el valor numérico (ej: 120), sino la propia cadena de caracteres (ej: "FIELD_AVG"). La función SYMGET recupera el contenido de la macrovariable tal cual (texto) y no lo interpreta como una referencia a una variable del dataset. Además, la gestión de las macrovariables durante la ejecución de un paso DATA es compleja porque no se actualizan línea por línea como se podría esperar para este tipo de operación.

La solución recomendada

Para resolver este problema de "resolución de cadena de caracteres a nombre de variable", es necesario abandonar la idea de una resolución dinámica por macro durante el paso DATA.

Existen dos enfoques principales:

1. Para un número reducido de variables: La condición explícita Si solo tiene unas pocas columnas posibles (como en nuestro ejemplo), el método más simple y eficiente sigue siendo el uso de bloques condicionales (IF/THEN/ELSE o SELECT).

1DATA target_ds;
2 SET source_ds;
3
4 SELECT (req_stat);
5 WHEN ('FIELD_AVG') field_stat = field_avg;
6 WHEN ('FIELD_SUM') field_stat = field_sum;
7 OTHERWISE field_stat = .;
8 END;
9RUN;
2. Para un gran número de variables: La generación de código Si usted procesa cientos de columnas, escribir condiciones manualmente se vuelve tedioso. La solución entonces consiste en generar el código SAS© antes de la ejecución.

Puede utilizar los metadatos de la tabla para construir dinámicamente una instrucción SELECT o una serie de IF a través de una macro de preprocesamiento. Esto permite que el código sea genérico y adaptable, independientemente de la estructura de la tabla.

En SAS©, una cadena de caracteres que contiene un nombre de variable sigue siendo texto. Para acceder al contenido de esta variable, es preferible utilizar estructuras lógicas explícitas o pasar por arrays (arreglos) o código generado dinámicamente, en lugar de depender de SYMGET que no está diseñado para la indirección de variables en el sentido estricto.