Data Step

Comment récupérer la valeur d'une variable dont le nom est stocké dans une autre colonne ?

Simon 5 views

Il arrive fréquemment, lors de la manipulation de données complexes sous SAS©, que l'on se heurte à un problème de référencement dynamique. Imaginez un jeu de données où une colonne ne contient pas une donnée brute, mais le nom d'une autre variable du tableau dont on souhaite extraire la valeur.

Le Scénario

Prenons l'exemple d'un dataset contenant des statistiques (FIELD_AVG, FIELD_SUM) et une colonne de contrôle nommée REQ_STAT.

Cette colonne REQ_STAT indique quelle statistique doit être retenue pour la ligne en cours.

  • Si REQ_STAT vaut "FIELD_AVG", nous voulons la valeur numérique de la colonne FIELD_AVG.

  • Si REQ_STAT vaut "FIELD_SUM", nous voulons la valeur de FIELD_SUM.

L'objectif est de créer une nouvelle variable, FIELD_STAT, qui contient cette valeur finale.

La fausse bonne idée : SYMPUT et SYMGET

Le premier réflexe de nombreux programmeurs est de tenter d'utiliser les fonctionnalités de macro-variable au moment de l'exécution (run time) via CALL SYMPUT et SYMGET.

Le code ressemble souvent à ceci :

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;
Pourquoi cela ne fonctionne pas ? Le résultat de ce code ne sera pas la valeur numérique (ex: 120), mais la chaîne de caractères elle-même (ex: "FIELD_AVG"). La fonction SYMGET récupère le contenu de la macro-variable tel quel (du texte) et ne l'interprète pas comme une référence à une variable du dataset. De plus, la gestion des macro-variables pendant l'exécution d'une étape DATA est complexe car elles ne se mettent pas à jour ligne par ligne comme on pourrait l'espérer pour ce type d'opération.

La solution recommandée

Pour résoudre ce problème de "résolution de chaîne de caractères en nom de variable", il faut abandonner l'idée d'une résolution dynamique par macro pendant l'étape DATA.

Deux approches principales existent :

1. Pour un petit nombre de variables : La condition explicite Si vous n'avez que quelques colonnes possibles (comme dans notre exemple), la méthode la plus simple et la plus performante reste l'utilisation de blocs conditionnels (IF/THEN/ELSE ou 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. Pour un grand nombre de variables : La génération de code Si vous traitez des centaines de colonnes, écrire des conditions manuellement devient fastidieux. La solution consiste alors à générer le code SAS© avant l'exécution.

Vous pouvez utiliser les métadonnées de la table pour construire dynamiquement une instruction SELECT ou une série de IF via une macro de pré-traitement. Cela permet de rendre le code générique et adaptable quelle que soit la structure de la table.

En SAS©, une chaîne de caractères contenant un nom de variable reste du texte. Pour accéder au contenu de cette variable, il est préférable d'utiliser des structures logiques explicites ou de passer par des tableaux (Arrays) ou du code généré dynamiquement, plutôt que de s'appuyer sur SYMGET qui n'est pas conçu pour l'indirection de variables au sens strict.