Data Step

Wie extrahiert man effektiv die letzten Beobachtungen aus einer Tabelle?

Simon 11 views

Bei der Datenexploration oder beim Debugging möchte man häufig nur das "Ende" einer Tabelle (Datensatz) isolieren. Im Gegensatz zur Option OBS=10, die uns den Anfang gibt, erfordert das Abrufen der letzten 10 Beobachtungen einer Tabelle mit $N$ Zeilen einen durchdachteren Ansatz, insbesondere wenn die Tabelle groß ist.

Hier ist eine Zusammenstellung der besten Methoden aus der SAS©-Community, klassifiziert nach Leistung und Anwendungsfall.

Note :
Der naive Ansatz (absteigende Sortierung)
Die erste Idee, die oft in den Sinn kommt, ist, die Tabelle in umgekehrter chronologischer Reihenfolge zu sortieren und die ersten Zeilen zu nehmen.
1PROC SORT DATA=MA_TABLE out=sorted_table;
2 BY descending date_variable;
3RUN;
4 
5DATA last_ten;
6 SET sorted_table (obs=10);
7RUN;
Urteil: Bei großen Tabellen vermeiden.

Warum? Das Sortieren einer Tabelle mit Millionen von Zeilen verbraucht enorm viele CPU- und E/A-Ressourcen, nur um 10 Zeilen zu lesen. Das ist ineffizient.
Note :
Der arithmetische Ansatz (NOBS und IF)
Eine viel sauberere Methode besteht darin, die Option NOBS in der SET-Anweisung zu verwenden. Diese Option speichert die Gesamtzahl der Beobachtungen in einer temporären Variable während der Kompilierung, ohne die Tabelle lesen zu müssen.
1DATA last_ten;
2 SET MA_TABLE nobs=total_obs;
3 /* On ne garde que si le numéro de ligne (_N_) est dans les 10 derniers */
4 IF _N_ > (total_obs - 10);
5RUN;
Urteil: Gut für mittelgroße Tabellen.

Warum? Obwohl wir nur 10 Zeilen behalten, muss SAS© die gesamte Tabelle sequenziell bis zum Ende lesen, um die IF-Bedingung zu prüfen. Bei einer Tabelle mit einer Milliarde Zeilen wird dies langsam sein.
Note :
Der Hochleistungsansatz (Direktzugriff mit POINT=)
Dies ist die von Experten empfohlene optimale Lösung. Ziel ist es, den Direktzugriff (Direct Access) zu nutzen, um direkt zum Ende der Datei zu springen, ohne den Anfang zu lesen.

Wir kombinieren NOBS (um das Ende zu kennen) und POINT (um zu einer bestimmten Zeile zu gehen).
1DATA last_ten;
2 /* Boucle de la ligne N-9 jusqu'à la ligne N */
3 DO i = (total_obs - 9) to total_obs;
4 SET MA_TABLE nobs=total_obs point=i;
5 OUTPUT;
6 END;
7 stop; /* IMPORTANT : stop évite une boucle infinie avec l'instruction POINT */
8RUN;
Urteil: Die beste Leistung.

Warum? SAS© liest nur 10 Zeilen, selbst wenn die Tabelle 100 Millionen enthält. Die Ausführung ist nahezu sofort.

Technische Anmerkung: Die STOP-Anweisung ist obligatorisch, da die SET-Anweisung mit POINT= niemals auf einen End-of-File-Marker trifft.
Note :
Der Makro-Ansatz (dynamisches FIRSTOBS)
Eine interessante Alternative besteht darin, den Startpunkt in einem vorherigen Schritt zu berechnen und dann die Option FIRSTOBS zu verwenden.
1/* Étape 1 : Calculer le point de départ */
2DATA _null_;
3 SET MA_TABLE nobs=n;
4 start_point = n - 9;
5 call symput('start_obs', start_point);
6RUN;
7 
8/* Étape 2 : Lire à partir de ce point */
9DATA last_ten;
10 SET MA_TABLE (firstobs=&start_obs);
11RUN;
Urteil: Funktional, aber wortreich. Methode 3 bleibt überlegen, da sie in einem einzigen Data-Schritt enthalten ist.

Punkte zur Beachtung und Einschränkungen

Zusammenfassend sind hier einige technische Nuancen, die in der Diskussion angesprochen wurden:

  1. Views und DBMS: Die Methoden, die NOBS und POINT= verwenden, funktionieren perfekt auf nativen Base SAS© Tabellen. Sie können jedoch bei Views oder externen Datenbanktabellen (Oracle, SQL Server über SAS©/ACCESS) fehlschlagen, da diese Engines die Anzahl der Zeilen nicht immer im Voraus kennen oder den direkten Zugriff nach Zeilennummer nicht unterstützen.

  2. Die Variable _N_: In Methode 3 können Sie die automatische Variable _N_ als Schleifenzähler verwenden (anstelle von i).

    • Vorteil: _N_ wird nicht in die Ausgabetabelle geschrieben (keine Notwendigkeit für DROP).

    • Nachteil: Dies kann für Anfänger verwirrend sein, da _N_ normalerweise die Anzahl der Iterationen des Data-Schritts bezeichnet.

Zusammenfassend: Für eine große, klassische SAS©-Tabelle sollten Sie immer die Methode 3 (POINT=) bevorzugen.