Posts Tagged ‘_N_’

h1

Repérer les 1ers/derniers records (FIRST/LAST)

mai 6, 2008

Repérer la première et/ou la dernière observation d’un jeu de données ou d’un sous-ensemble de ce jeu, c’est possible sous SAS avec les mots-clés FIRST et LAST dans un data step. On se sert de cette information sous forme de condition. Si la première observation est rencontrée, on fait ceci, sinon on fait cela. Cela sert pour créer une variable compteur ou pour générer plusieurs programmes via un DATA _NULL_, programmes variant par quelques valeurs listées dans un fichier de référence.

1. Le raisonnement FIRST/LAST en langage humain

Dans l’exemple ci-dessous, on a tout d’abord deux variables MEMNAME et NAME qui sont triées. Ensuite sont ajoutées plusieurs variables.

Les variables FRST_DSN/LST_DSN

  • S’il s’agit de la première fois que l’on lit la valeur de la variable MEMNAME, alors on donne une value de 1 à FRST_DSN, sinon on donne une valeur de 0.
  • Si au contraire, il s’agit de la dernière valeur avant de changer, LST_DSN prend la valeur 1, sinon il prend la valeur 0.

Dans l’exemple, on remarque que FRST_DSN et LST_DSN sont toutes les deux égale à 1 quand MEMNAME=DSN2, car il n’y a qu’une observation pour ce MEMNAME. La première observation est donc également la dernière,

memname  name  frst_dsn lst_dsn frst_var lst_var
    dsn1       var1          1          0           1          0
    dsn1       var1          0          0           0          0
    dsn1       var1          0          0           0          1
    dsn1       var2          0          0           1          1
    dsn1       var3          0          1           1          1    
    dsn2       var1          1          1           1          1    

    dsn3       var1          1          0           1          1
    dsn3       var2          0          0           1          1
    dsn3       var3          0          0           1          1
    dsn3       var4          0          1           1          1    
    dsn4       var1          1          0           1          1
    dsn4       var2          0          1           1          1       

FRST_VAR/LST_VAR : une fois dans un groupe (DSN1, DSN2, DSN3 ou DSN4), on regarde la seconde variable NAME.

  • Si on a la première fois la valeur dans ce groupe, FRST_VAR=1 sinon FRST_VAR=0.
  • Si au contraire, il s’agit de la dernière fois qu’on l’observe dans ce group, LST_VAR=1, 0 autrement.

Dans l’exemple, seul le DSN1 a plusieurs fois une VAR1 associée. C’est donc le seul moment où FRST_VAR n’est pas égal à LST_VAR.

NOTE, choix de l’auteur : entendez FRST pour rappeler le mot FIRST (premier), LST le mot LAST (dernier) et DSN le mot DATA SET NAME (nom du jeu de données).

2. Le raisonnement FIRST/LAST en langage SAS

SAS lie les données d’un jeu de données ligne par ligne. On rassemble les données par groupe en les triant. On rappelle cet ordre avec une instruction BY.

Ici les variables MEMNAME et NAME sont extraites de la bibliothèque SASHELP grâce au dictionnaire COLUMN.

proc sql;
   create table lst_dsn_var as
   select memname, name
   from dictionary.columns
   where upcase(libname)=’SASHELP’;
quit;

Puis, chacune des variables FRST_DSN, LST_DSN, FRST_VAR et LST_VAR sont crées. Ces variables prennent une valeur de 1, si la condition est vrai (s’il s’agit bien de la première ou de la dernière observation), 0 sinon. Bien sûr, on peut choisir de leur donner la valeur que l’on veut.

data _null_;
   set lst_dsn_var;
   by memname name;
   if first.memname then frst_dsn=1;
   else frst_dsn=0;
   if last.memname then lst_dsn=1;
   else lst_dsn=0;
   if first.name then frst_var=1;
   else frst_var=0;
   if last.name then lst_var=1;
   else lst_var=0;
run;

NOTE : SAS se base sur les données d’origine pour dire si oui ou non, il s’agit de la première/dernière observation. Dès lors, si le jeu d’origine est altéré (suppression de lignes), SAS ne redéfinira pas une première/dernière observation parmi celles restantes. On peut donc ne plus avoir l’observation considérée par SAS comme première/dernière. Il choisira si besoin de faire les deux opérations dans des data steps distincts.

3. La première et la dernière observation d’un data set

Vous n’aurez pas toujours une variable prenant la même valeur pour toutes les observations et ainsi retrouver la première et la dernière observation. On peut soit en créer une avec un RETAIN par exemple ou plus simplement utiliser

  • la variable automatique _N_ pour la première observation et
  • la variable assignée avec l’option END= dans l’instruction SET pour la dernière observation.

data _null_;
   set lst_dsn_var end=eof;
   if _N_=1 then …;
   if eof then…;
run;

NOTE : Par habitude, on donne ici le nom EOF (End Of File) comme nom à la variable qui prend une valeur 1 s’il s’agit de la dernière observation, 0 autrement. Comme la variable automatique _N_, EOF n’apparaît pas dans le data set final, s’il est créé.

h1

Combien d’observations dans mon data set ?

avril 14, 2008

Savoir trouver le nombre d’observations dans un data set SAS : tel est le sujet d’aujourd’hui. Connaître le nombre d’observations dans un jeu de données présente plusieurs avantages. En voici deux :

  • Définir une condition pour qu’un code soit exécuté.
  • Définir une boucle pour exécuter un code autant de fois qu’il y a d’observations dans le data set d’origine.

Dans les deux cas, on choisi ici de sauvegarder ce nombre dans une macro variable. Quelles sont les méthodes à disposition pour trouver ce nombre ? Je vous en propose d’en détailler six. Celles-ci fonctionnent également lorsque le data set est vide d’observations.

Exemples illustrés avec le data set ORIG : pour illustrer les différentes méthodes, j’utilise un jeu de données nommé ORIG ne contenant pas d’observations.

data orig;
x=1;

*if x=1 then output;
if x=1 then delete;
run;

L’instruction %PUT permet de voir la valeur de mes macro variables dans la LOG.

1. La fonction COUNT dans PROC SQL : la procédure SQL et sa fonction COUNT permettent de retrouver le nombre total d’observations dans le data set lu, si on n’utilise pas de GROUP BY. L’étoile signifie « TOUTES LES OBSERVATIONS », indépendamment de la variable. Si le nombre d’observations est stocké dans une variable, la valeur s’affiche pour chaque observation. Comme cette valeur est la même pour toutes les observations, on peut n’en afficher qu’une seule via DISTINCT. On peut sauvegarder cette information dans une macro variable via INTO:. Si le DISTINCT n’est pas utilisé, seule la première valeur sera sauvegardé dans la macro variable. DISTINCT est donc optionnel dans ce cas précis.

proc sql noprint;
select distinct count(*) into: methode1
from orig;
quit;

%put METHOD 1 = &methode1. ;


2. SQLOBS, une macro variable automatique à utiliser avec précaution : lorsqu’un data set est créé avec une procédure SQL, on peut, juste après, retrouver l’information avec la macro variable automatique &SQLOBS. Il faut bien faire attention de ne pas inclure d’autres data sets entre temps, lors d’une mise à jour par exemple. SQLOBS récupère le nombre d’observations du dernier jeu de données quelque soit son nom.

proc sql ;
create table methode2 as
select *
from orig;
quit;

%put METHODE 2 = &sqlobs. ;

3. Les métadonnées des dictionnaires SAS : le dictionnaire TABLES liste tous les data sets de toutes les bibliothèques et des informations supplémentaires les caractérisant. Ainsi la variable NOBS contient le nombre d’observations dans le data set. Ici on choisi INTO: pour sauvegarder ce nombre dans une macro variable.

proc sql noprint;
select nobs into: methode3
from dictionary.tables
where upcase(libname)=’WORK’ and
upcase(memname)=’ORIG’;
quit;

%put METHODE 3 = &methode3. ;

4. ATTRN comme « SAS Component Language » ou SCL : le SCL nommé ATTRN permet d’accéder au nombre d’observations. Pour cela, le nom du data set en question et le mot clé NOBS sont données. Ce SCL est accessible via %SYSFUNC. Pour lire le data set et extraire cette information, il faut au préalable, l’ouvrir et ensuite le fermer pour éviter des bugs, via les SCL OPEN et CLOSE. On réfère donc au data set via la macro variable DSID ouvrant le data set.

%let dsid     = %sysfunc(open(work.orig,in));
%let methode4 = %sysfunc(attrn(&dsid,nobs));
%if &dsid. > 0 %then %let rc = %sysfunc(close(&dsid));

%put METHODE 4 = &methode4. ;

5. La variable automatique _N_ : dans un data step, une variable nommée _N_ est créée automatique. Elle contient le nombre total d’itérations effectuées par SAS. Ainsi, si aucune donnée n’est lue, _N_=1. Une fois la lecture d’une observation faite par exemple, SAS revient juste après l’instruction DATA et _N_ est incrémenté de 1. Le nombre d’observations dans le data set est donc _N_-1. Ce nombre est sauvegardé ici dans une macro variable appelée METHODE5 créée via une instruction CALL SYMPUTX.

data_null_;
call symputx(‘methode5’,_N_-1);
set orig;
run;

%put METHODE 5 = &methode5. ;

6.  L’option NOBS de l’instruction SET : en précisant un nom après l’option NOBS= de l’instruction SET, la valeur de NOBS est sauvegardée dans une variable. Ici, elle s’appelle METHODE6. L’instruction CALL SYMPUTX permet de sauvegarder cette valeur dans une macro variable. La manière dont SAS traite le code est très importante ici.  Les explications d’Alain vous sont données plus bas.

data _null_;
if 0 then set orig nobs=methode6;
call symputx(‘methode6’,methode6);
stop;
run;

Le « IF 0 » est une instruction toujours fausse, donc l’exécution de l’instruction
conditionnée ne sera jamais réalisée. La récupération du nombre d’observations
depuis le dictionnaire du data set se fait au moment de la compilation par le SAS DATA
COMPILER, qui stocke dans une variable qui est forcément temporaire citée avec
l’option « NOBS= ».

L’instruction STOP ne permet pas d’écourter le temps de lecture des données car il
n’y pas d’exécution de lecture. Alors que se passe-t-il ?

L’étape DATA étant une boucle automatique dès qu’une instruction de lecture (Set ,
Merge, Modify, Update, …) de data set est détectée par le Superviseur SAS et par
compilateur de l’étape DATA , l’exécution de la boucle est automatique à cause de la
détection de l’instruction « SET » et SAS va vérifier si le test
induit par l’instruction « IF 0 » (comprendre if 0 =1) n’est pas devenu vrai !
D’où la nécessité de poser l’instruction SAS « STOP », pour éviter la boucle de
l’étape DATA.

 

(SUPERVISEUR SAS : Agent pivot qui distribue le code soumis par PARSING, soit au
DATASTEP COMPILER, PROCEDURE PARSER ou au Compilateur MACRO)

h1

Ecrire un texte avec l’instruction PUT

février 24, 2008

pen_fr.jpg 

Faire apparaître un message d’erreur dans la log ; afficher la valeur de variables dans la log lors du développement d’un programme ; générer plusieurs programmes similaires : voici autant d’applications de l’instruction PUT, propre au data step, qui affiche, par défaut, le texte dans la log.

1. Taper du texte brut : en mettant votre texte entre guillemets dans l’instruction PUT, celui-ci apparaîtra dans la log.

Couper l’instruction PUT : lorsqu’une instruction PUT devient longue, on doit se déplacer sur plusieurs écrans pour voir l’intégralité du programme. En coupant le texte, la lisibilité du programme et le confort du programmeur se trouvent améliorés et le texte reste continue dans la sortie LOG ou autre.

Ecrire des guillemets : pour afficher une guillemet simple, celle-ci devra apparaître dans des guillemets doubles et inversement. Pour afficher deux guillemets simples, il faudra les séparer dans deux jeux de guillemets doubles. Par défaut, on privilégiera les guillemets simples pour alléger le programme.

Ajouter un saut de ligne : à chaque nouvelle instruction PUT, SAS crée un saut de ligne. Les barres inclinées (slash /) ajoutent autant de sauts de ligne supplémentaires que désirés.

Ajouter des espaces : en écrivant une procédure SQL, on fait utile des indentations améliorant la lisibilité du code. Soit ces espaces de début de ligne sont ajoutés manuellement entre les guillemets, soit un arobas suivi du nombre d’espaces précède les guillemets (@6 crée une indentation de six espaces). 

Enlever l’espace créé par défaut avant un début de guillemets : plusieurs jeux de guillemets sont fréquemment utilisés pour insérer entre les deux le nom d’une variable. Au final, il est parfois important que la valeur de la variable et le texte qui suit se suivent sans espace. Pour cela, il faut faire reculer le curseur d’un espace en ajoutant  +(-1) avant le début de la guillemet.

2. Afficher les valeurs des variables d’un jeu de données

Afficher la valeur de la variable : pour voir la valeur des variables, il faut lister leur nom dans l’instruction PUT sans guillemet. C’est très pratique pour générer un code variant uniquement par la valeur de variables.

Afficher la valeur d’une variable et son nom : lorsqu’il s’agira de débugger un programme, vous repérerez plus rapidement dans la log vos valeurs si le nom de la variable apparaît également. Pour ce faire, vous avez deux options plus ou moins rapide.

  • Utiliser les guillemets vous obligera à écrire le nom de la variable deux fois : une fois entre guillemets et une fois sans guillemet.
  • Plus simplement, le nom de la variable est suivi du signe égal.

Lectures complémentaires : l’instruction PUT trouve tout son potentiel en combinaison avec d’autres instructions : 

  • Pas de jeu de données (DATA _NULL) : l’instruction PUT est propre au data step. Quand vous ne voudrez pas créer un jeu de données SAS dans ce data step, vous aurez besoin du DATA _NULL_.
  • Changer de destination (FILE/FILENAME) : Pour diriger votre texte vers une autre sortie que la log, vous aurez besoin de l’instruction FILE. Selon que cette sortie sera vers un fichier externe ou vers la fenêtre OUTPUT de SAS, vous aurez besoin de l’instruction globale FILENAME ou non.
  • Alterner selon les valeurs des variables (BY/FIRST/LAST) : pour générer des codes variant selon la valeur de variables, il y a l’instruction BY en combinaison avec FIRST et LAST.
  • Début et fin de texte (_N_/END=) : pour afficher un texte unique en début et en fin, on peut faire référence à la variable automatique _N_ (if _N_=1) et à une variable définie avec l’option END= de l’instruction SET.