Lors de l'exploration de données ou du débogage, il est fréquent de vouloir isoler uniquement la "fin" d'une table (dataset). Contrairement à l'option OBS=10 qui nous donne le début, récupérer les 10 dernières observations d'une table contenant $N$ lignes demande une approche plus réfléchie, surtout si la table est volumineuse.
Note : L'approche naïve (Tri Décroissant)
La première idée qui vient souvent à l'esprit est de trier la table par ordre chronologique inverse et de prendre les premières lignes.
proc sort data=MA_TABLE out=sorted_table;
by descending date_variable;
run;
data last_ten;
set sorted_table (obs=10);
run;
1
PROC SORTDATA=MA_TABLE out=sorted_table;
2
BY descending date_variable;
3
RUN;
4
5
DATA last_ten;
6
SET sorted_table (obs=10);
7
RUN;
Verdict : À éviter sur les grosses tables.
Pourquoi ? Trier une table de millions de lignes consomme énormément de ressources CPU et I/O simplement pour lire 10 lignes. C'est inefficace.
Note : L'approche arithmétique (NOBS et IF)
Une méthode beaucoup plus propre consiste à utiliser l'option NOBS dans l'instruction SET. Cette option stocke le nombre total d'observations dans une variable temporaire lors de la compilation, sans avoir à lire la table.
data last_ten;
set MA_TABLE nobs=total_obs;
/* On ne garde que si le numéro de ligne (_N_) est dans les 10 derniers */
if _N_ > (total_obs - 10);
run;
1
DATA 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 */
Note : L'approche haute performance (Accès Direct avec POINT=)
C'est la solution optimale recommandée par les experts. L'objectif est d'utiliser l'accès aléatoire (Direct Access) pour sauter directement à la fin du fichier sans lire le début.
On combine NOBS (pour connaître la fin) et POINT (pour aller à une ligne précise).
data last_ten;
/* Boucle de la ligne N-9 jusqu'à la ligne N */
do i = (total_obs - 9) to total_obs;
set MA_TABLE nobs=total_obs point=i;
output;
end;
stop; /* IMPORTANT : stop évite une boucle infinie avec l'instruction POINT */
run;
1
DATA 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 */
Note technique : L'instruction STOP est obligatoire car l'instruction SET avec POINT= ne rencontre jamais de marqueur de fin de fichier (End-of-File).
Note : L'approche Macro (FIRSTOBS dynamique)
Une alternative intéressante consiste à calculer le point de départ dans une étape précédente, puis à utiliser l'option FIRSTOBS.
/* Étape 1 : Calculer le point de départ */
data _null_;
set MA_TABLE nobs=n;
start_point = n - 9;
call symput('start_obs', start_point);
run;
/* Étape 2 : Lire à partir de ce point */
data last_ten;
set MA_TABLE (firstobs=&start_obs);
run;
1
/* Étape 1 : Calculer le point de départ */
2
DATA _null_;
3
SET MA_TABLE nobs=n;
4
start_point = n - 9;
5
call symput('start_obs', start_point);
6
RUN;
7
8
/* Étape 2 : Lire à partir de ce point */
9
DATA last_ten;
10
SET MA_TABLE (firstobs=&start_obs);
11
RUN;
Verdict : Fonctionnel mais verbeux. La méthode 3 reste supérieure car elle tient en une seule étape Data.
Points d'attention et Limitations
Pour conclure, voici quelques nuances techniques soulevées lors de la discussion :
Die auf WeAreCAS.eu bereitgestellten Codes und Beispiele dienen Lehrzwecken. Es ist zwingend erforderlich, sie nicht blind in Ihre Produktionsumgebungen zu kopieren. Der beste Ansatz besteht darin, die Logik zu verstehen, bevor sie angewendet wird. Wir empfehlen dringend, diese Skripte in einer Testumgebung (Sandbox/Dev) zu testen. WeAreCAS übernimmt keine Verantwortung für mögliche Auswirkungen oder Datenverluste auf Ihren Systemen.
SAS und alle anderen Produkt- oder Dienstleistungsnamen von SAS Institute Inc. sind eingetragene Marken oder Marken von SAS Institute Inc. in den USA und anderen Ländern. ® zeigt die Registrierung in den USA an. WeAreCAS ist eine unabhängige Community-Site und nicht mit SAS Institute Inc. verbunden.
Diese Website verwendet technische und analytische Cookies, um Ihre Erfahrung zu verbessern.
Mehr erfahren.