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 :
Les codes et exemples fournis sur WeAreCAS.eu sont à but pédagogique. Il est impératif de ne pas les copier-coller aveuglément sur vos environnements de production. La meilleure approche consiste à comprendre la logique avant de l'appliquer. Nous vous recommandons vivement de tester ces scripts dans un environnement de test (Sandbox/Dev). WeAreCAS décline toute responsabilité quant aux éventuels impacts ou pertes de données sur vos systèmes.
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.