Data Step

Wie man den Wert einer Variablen abruft, deren Name in einer anderen Spalte gespeichert ist?

Simon 3 vues

Bei der Bearbeitung komplexer Daten in SAS© stößt man häufig auf das Problem der dynamischen Referenzierung. Stellen Sie sich einen Datensatz vor, bei dem eine Spalte keine Rohdaten, sondern den Namen einer anderen Variablen aus der Tabelle enthält, deren Wert Sie extrahieren möchten.

Das Szenario

Nehmen wir das Beispiel eines Datasets, das Statistiken (FIELD_AVG, FIELD_SUM) und eine Kontrollspalte namens REQ_STAT enthält.

Diese Spalte REQ_STAT gibt an, welche Statistik für die aktuelle Zeile herangezogen werden soll.

  • Wenn REQ_STAT "FIELD_AVG" ist, möchten wir den numerischen Wert der Spalte FIELD_AVG.

  • Wenn REQ_STAT "FIELD_SUM" ist, möchten wir den Wert von FIELD_SUM.

Ziel ist es, eine neue Variable, FIELD_STAT, zu erstellen, die diesen Endwert enthält.

Die vermeintlich gute Idee: SYMPUT und SYMGET

Der erste Reflex vieler Programmierer ist der Versuch, Makrovariablen-Funktionalitäten zur Laufzeit (run time) über CALL SYMPUT und SYMGET zu verwenden.

Der Code sieht oft so aus:

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;
Warum funktioniert das nicht? Das Ergebnis dieses Codes wird nicht der numerische Wert (z.B. 120) sein, sondern die Zeichenfolge selbst (z.B. "FIELD_AVG"). Die Funktion SYMGET ruft den Inhalt der Makrovariablen unverändert (als Text) ab und interpretiert ihn nicht als Referenz auf eine Variable im Datensatz. Darüber hinaus ist die Verwaltung von Makrovariablen während der Ausführung eines DATA-Schritts komplex, da sie sich nicht Zeile für Zeile aktualisieren, wie man es für diese Art von Operation erwarten würde.

Die empfohlene Lösung

Um dieses Problem der "Auflösung einer Zeichenfolge in einen Variablennamen" zu lösen, muss man die Idee einer dynamischen Makroauflösung während des DATA-Schritts aufgeben.

Es gibt zwei Hauptansätze:

1. Für eine kleine Anzahl von Variablen: Die explizite Bedingung Wenn Sie nur wenige mögliche Spalten haben (wie in unserem Beispiel), ist die einfachste und effizienteste Methode die Verwendung von bedingten Blöcken (IF/THEN/ELSE oder 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. Für eine große Anzahl von Variablen: Die Codegenerierung Wenn Sie Hunderte von Spalten verarbeiten, wird das manuelle Schreiben von Bedingungen mühsam. Die Lösung besteht dann darin, den SAS©-Code vor der Ausführung zu generieren.

Sie können die Metadaten der Tabelle verwenden, um dynamisch eine SELECT-Anweisung oder eine Reihe von IF-Anweisungen über ein Vorverarbeitungs-Makro zu erstellen. Dadurch wird der Code generisch und anpassbar, unabhängig von der Tabellenstruktur.

In SAS© bleibt eine Zeichenfolge, die einen Variablennamen enthält, Text. Um auf den Inhalt dieser Variablen zuzugreifen, ist es vorzuziehen, explizite logische Strukturen zu verwenden oder über Arrays oder dynamisch generierten Code zu gehen, anstatt sich auf SYMGET zu verlassen, das nicht für die indirekte Variablenauflösung im strengen Sinne konzipiert ist.