Posts Tagged ‘EOF’

h1

Passer d’un fichier de l’ODS TAGSET.EXCELXP à un data set SAS avec PROC IMPORT

août 15, 2008

Le programmeur SAS pourra recueillir des informations d’un non spécialiste en créer un fichier Excel. Il importe ensuite les données sous SAS.

Dans un précédent sujet « Mes 1ers pas avec ODS TAGSET.EXCELXP« , nous avons vu comment créer un fichier Excel, ou plutôt un fichier XML lisible sous Excel, à partir de la syntaxe d’ODS TAGSET.EXCELXP.

Maintenant, il s’agit de voir les limites de l’importation d’un fichier XML avec la procédure PROC IMPORT.

Exemple : Nous aurons un fichier LST_STUDY.XLS avec plusieurs feuillets, dont un nommé ‘2000’, comme exemple. Ce feuillet a deux colonnes : le numéro de l’étude (STUDY) et la variable à compléter manuellement (FLAG_EXTERNAL). La première ligne contient le nom de la colonne. La variable STUDY peut contenir des nombres et du texte.

1. PROC IMPORT a besoin de données Excel

Même si le fichier créé par ODS TAGSET.EXCELXP a une extension .xls, ce fichier est en fait un fichier en langage XML. Comment observer cette information ? Voici deux propositions :

  1. Ouvrez un fichier de ce type sous Excel et regarder le type lors que la fenêtre OUVRIR apparaît.
  2. Ouvrez le fichier dans un éditeur de texte

Afin d’utiliser la procédure PROC IMPORT, il faudra donc convertir le fichier en « enregistrant sous » et là choisir le standard Excel.

2. Les options de l’instruction PROC IMPORT

Préciser le nom du fichier d’entrée et celui de sortie : Dans l’instruction PROC IMPORT, le nom du fichier Excel est donné avec l’option DATAFILE=; celui du data set SAS est introduit par l’option OUT=. Pour rendre ce data set permanent, le nom de la bibliothèque précédera le nom du data set comme d’habitude.

Indiquer à SAS le type de fichier à lire : Selon l’environnement et la version Excel utilisée, l’option DBMS= variera. DBMS=XLS est l’option que j’utilise sous Unix et Windows pour Excel2003. Reportez-vous à la documentation en ligne PROC IMPORT Statement) pour connaître toutes les valeurs possibles de cette option.

Remplacer un fichier SAS existant : Si le data set SAS existe déjà, il ne sera pas remplacé, à moins d’ajouter l’option REPLACE.

%let resultats = C:/sasref;

proc import datafile = « &resultats./lst_study.xls »
            out      = lst_study
            dbms     = xls
            replace;
run;

3. Les Instructions sur les données sources

Après avoir vu les options de l’instruction PROC IMPORT, je vous propose trois instructions supplémentaires de la procédure (SAS Online Doc. : Data Source Statements)

Des noms de variables personnalisés avec GETNAMES=YES : SAS se sert de la première ligne du fichier Excel pour définir le nom des variables SAS à moins que l’instruction GETNAMES=NO soit ajoutée.

SAS considère les premières lignes du fichier pour identifier le type des variables sauf si MIXED=YES : Si on a une combinaison de caractères et chiffres, on peut se retrouver avec des valeurs manquantes. Par exemple, si vous avez une variable année contenant les valeurs 2008, 2007, <2007, il faudra importer les variables sous forme de caractère. L’instruction MIXED=YES fera le travail pour vous. 

Importer une feuille de calcul en particulier grâce à SHEET=: Par défaut, SAS importera la première feuille de calcul disponible dans le fichier Excel. Pour choisir un autre feuillet, son nom est donné entre guillemets dans l’instruction  SHEET=.

%let resultats = C:/sasref;

proc import datafile = « &resultats./lst_study.xls »
            out      = lst_study
            dbms     = xls
            replace;
   *getnames = yes;
   mixed    = yes;
   sheet    = ‘2000’;
run;

Vous trouverez plus d’informations sur la procédure PROC IMPORT dans l’aide en ligne : SAS Online Doc, The IMPORT Procedure.

4. Une spécificité de l’ODS TAGSET.EXCELXP à gérer

Lors de la création du fichier avec ODS TAGSET.EXCELXP, une ligne est parfois ajoutée après la dernière ligne de saisie. Cette ligne est incluse dans le data set SAS à l’importation. La raison pour laquelle cette ligne est saisie m’est inconnue.

Par contre, je vous propose un data step pour vous en débarrasser une fois le data set SAS créé. 

  • L’option END= de l’instruction SET sert à repérer la dernière ligne d’observations.
  • La fonction MISSING permet de ne supprimer la ligne que si notre variable STUDY est vide.

data lst_study;
   set lst_study end=eof;
   if eof and missing(study) then delete;
run;

h1

Insérer quelques nouvelles observations

juin 9, 2008

Dans l’article ‘Ajouter des lignes en combinant des data sets’, nous avons vu comment ajouter des observations en joignant plusieurs data sets. Ici, il s’agit de voir comment ajouter manuellement un nombre limité d’observations en fin de data set. Deux méthodes sont proposées : un data step avec l’option END= et l’instruction OUTPUT d’une part et l’instruction INSERT INTO de PROC SQL d’autre part.

1. Passer par un data step pour ajouter une ou plusieurs observations

L’instruction SET dispose de l’option END=. Celle-ci permet de définir une nouvelle variable. On peut s’imaginer cette variable comme une variable binaire prenant une valeur zéro pour toutes les observations sauf la dernière. Il est courant de nommer cette variable EOF, acronyme pour END OF FILE (fin de fichier).

Dans un premier temps, toutes les observations sont lues et envoyées dans le data set de sortie avec OUTPUT.

Dans un second temps, on précise à SAS que si notre variable binaire a une valeur de 1, l’observation va être de nouveau envoyée dans le data set final après avoir changé les valeurs de son choix.

Lorsque la valeur prise par la variable binaire n’est pas précisée (if eof then…), SAS assume ‘if eof=1 then…’ ou en d’autres termes ‘si la condition est vraie alors…’. Pour information, l’inverse est ‘if not eof then…’ ou ‘if eof=0 then…’.

data class;
   set sashelp.class end=eof;
   output;
   if eof then
      do;
         name=‘SASREF’;
         sex=‘F’;
         age=18;
         height=.;
         weight=100;
         output;
         name=‘SASREF’;
         sex=‘M’;
         age=.;
         height=.;
         weight=.;
         output;
      end;
run;

Cette méthode reste très contraignante. Car il faut redéfinir tous les champs au risque sinon d’avoir une valeur de l’ancienne observation. La procédure SQL est véritablement conçue pour répondre à notre besoin.

2. L’instruction INSERT de la procédure PROC SQL

Deux syntaxes sont disponibles avec l’instruction INSERT selon qu’on liste seulement les valeurs, mais pour toutes les variables ou qu’on liste à la fois les variables et leur valeurs mais seulement celles qui nous intéresse.

Ma préférence va à la seconde solution, car elle évite des erreurs dans l’ordre d’affichage des valeurs. De plus, lorsqu’on relit un programme, il est facile de faire le lien entre une valeur et la variable à laquelle elle réfère.

 2.1 Lister toutes les valeurs pour une ligne d’observation sans le nom des variables : chaque nouvelle ligne d’observation est introduite par le mot-clé VALUES. Il n’y a donc pas besoin de délimiteur entre chaque ligne d’observation. Toutes les valeurs pour une observation donnée sont listées entre parenthèses et séparées par une virgule.

proc sql;
   insert into class
   values (‘SASREF2’,‘F’,18,.,100)
   values (‘REFSAS2’,‘M’,.,.,.);
quit;

 2.2 Lister les variables qui nous intéressent seulement : chaque nouvelle ligne d’observation est introduite par le mot-clé SET. Comme précédemment, il n’y a pas de délimiteur entre chaque ligne d’observation nouvellement définie. Les variables sont listées dans un ordre quelconque. Les variables non listées prennent une valeur manquante.

proc sql;
   insert into class
   set sex=‘F’, name=‘SASREF3’,age=18,weight=100
   set name=‘REFSAS3’, sex=‘M’;
quit;

Pour plus de précisions sur l’instruction INSERT, vous pouvez vous reporter à  la SAS Online Doc. : Insert Statement.

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éé.