Posts Tagged ‘%include’

h1

Quand compilation et exécution font la différence, un exemple

août 21, 2008

SAS effectue plusieurs lectures d’un programme. A la première lecture, c’est la compilation. A la seconde, c’est l’exécution. Connaître ces notions vous aidera à comprendre les exemples ci-dessous : pourquoi le premier code proposé ne fonctionne pas alors que les autres passent. Les fonctions PUT, VVALUE, le dictionnaire DICTIONARY.COLUMNS et le DATA _NULL_ serviront dans les exemples.

1. Un premier exemple avec la fonction PUT

Rappel sur la fonction PUT : Une fonction PUT permet de convertir une variable numérique en variable texte ou une variable texte en une autre variable texte. Elle est composée de deux paramètres. D’un côté, il y a la variable d’origine. De l’autre côté, il y a le format à appliquer sur cette variable d’origine. C’est donc la valeur sous forme formatée qui devient une valeur texte. Reportez vous à l’article « Convertir une variable caractère en numérique et inversement » pour plus de détails.

La phase de compilation : A la compilation, SAS  vérifie que la variable d’origine et le format associé sont tous les deux du même type. Il faut qu’une variable numérique est un format qui s’applique à une variable numérique. De manière identique, il faut un format caractère pour une variable texte.

La phase d’exécution : Si on ne connaît pas à l’avance le type de la variable, on peut avoir envie de définir une condition : si la variable est numérique applique tel format, sinon applique tel autre format. Hors une condition IF/THEN n’est visible par SAS qu’à la phase d’exécution.

En d’autres termes, SAS tentera d’appliquer un format numérique à une variable numérique avant de regarder si la fonction PUT est définie dans une condition.

data import_excel;
   retain type ‘CHAR’;
   study = ‘999’;
   output;
   study = ‘888’;
   output;
run;

data study_new;
   set import_excel;
   if type=‘NUM’ then study_new=put(study,best.);
   else study_new=study;
run;

Le résultat : Dans l’exemple, un format numérique (BEST.) est appliqué à une variable texte (STUDY). La première partie de la condition ne s’applique pas car le type de la variable n’est pas égal à NUM. Mais SAS cherche un format $BEST. qui n’existe pas. Il est obligé de s’arrêter là.

28 data study_new;
29 set ref;
30 if upcase(type)=’NUM’ then study_new=put(study,best.);
                                                  —–
                                                  48

ERROR 48-59: The format $BEST was not found or could not be loaded.

31 else study_new=study;
32 run;

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.STUDY_NEW may be incomplete.
When this step was stopped there were 0 observations and 3 variables
.

Un exemple où le type de la variable est inconnu : en important un fichier EXCEL (PROC IMPORT/MIXED=YES), le type de la variable sous SAS peut-être inconnu. La variable sera caractère si une cellule contient du texte. Sinon, elle sera numérique.

2. Une solution rapide

Une fonction Vxxx: la fonction VVALUE retourne une valeur texte. Elle utilise le format associé à la variable en interne pour construire la valeur sous forme formatée. La nouvelle variable aura une longueur de 200.

data study_new;
   set ref;
   if type=’NUM’ then study_new=vvalue(study);
   else study_new=study;
run;

3. Une solution plus lourde mais pouvant s’appliquer à plusieurs variables

Une autre solution est de générer le code à exécuter. Si la variable est numérique, c’est l’instruction avec PUT qui apparaîtra, sinon c’est l’autre instruction. Cette approche fait appel à la notion de dictionnaire et de DATA _NULL_.

3.1 Créer un data set contenant le nom des variables et leur type à partir du dictionnaire (dictionary) appelé COLUMNS

La première étape consiste à créer un data set, nommé DICT_REF, contenant la variable STUDY et son type.

Choix du dictionnaire : Le dictionnaire (dictionary) COLUMNS est un data set de référence, créé de manière automatique par SAS. Il répertorie toutes les variables contenues dans tous les data sets de toutes les bibliothèques actives. Il contient donc une ligne par variable.

Chaque ligne du dictionnaire contient plusieurs informations caractérisant cette variable dont :

  • la bibliothèque d’origine (variable LIBNAME)
  • le data set d’origine (variable MEMNAME)
  • le nom de la variable (variable NAME)
  • le type de la variable (variable TYPE).

Prendre un sous-ensemble du dictionnaire : Ici seule la variable STUDY est utile. Elle provient du data set EXCEL_IMPORT sauvegardé de manière temporaire dans la bibliothèque WORK.

Mettre en majuscule : Le type de la variable est soit « num » soit « char », toujours en minuscule. Le nom de la variable peut avoir un mélange de majuscules et minuscules selon la manière dont est saisi le nom lors de sa création. Pour éviter des surprises, le nom de la variable et le type sont mis en majuscule grâce à la fonction UPCASE. L’avantage des dictionnaires, c’est qu’ils peuvent lister plus d’une variable.

proc sql;
   create table dict_ref as
      select upcase(name) as name,
             upcase(type) as type
      from dictionary.columns
      where upcase(libname) = ‘WORK’ and
            upcase(memname) = ‘EXCEL_IMPORT’ and
            upcase(name)    = ‘STUDY’;
quit;

3.2 Ecrire le code et l’appeler

La deuxième étape consiste à créer un programme nommé TMP_STUD.SAS donc le nom et l’emplacement est défini dans l’instruction FILENAME. Pour écrire dans ce fichier, l’instruction FILE est ajoutée dans le DATA _NULL_. Pour plus de précisions sur l’instruction PUT, reportez-vous à l’article « Ecrire un texte avec l’instruction PUT« .

filename stud ‘C:/sasref/tmp_stud.sas’;

data _null_;
   set dict_ref;
   file stud;
   put ‘data study_new;’;
   put @3 ‘set excel_import;’;
   if type=‘NUM’ then put @3 ‘study_new=put(‘ name ‘,9.);’;
   else put @3 ‘study_new=’ name ‘;’;
   put ‘run;’;
run;

%include stud;
filename stud;

L’écriture du programme est fonction des informations contenues dans le DICT_REF. Si plus d’une variable est sélectionnée, il faudrait préciser deux choses :

  • Les instructions DATA et SET ne sont à écrire qu’une fois. Elles sont ajoutées lors de la première boucle fait en interne autour de l’étape DATA via « if _N_=1 ».
  • L’instruction RUN apparaît une fois en fin de programme. Il faut donc l’ajouter une fois le dernier record du fichier de référence atteint. L’option END= de l’instruction SET crée une variable interne prenant la valeur 0 pour tous les records sauf le dernier où elle prend la valeur 1. La condition est donc basée sur cette variable.

filename stud ‘C:/sasref/tmp_stud.sas’;

data _null_;
   set dict_ref end=eof;
   file stud;
   if _N_=1 then
      do;
         put ‘data study_new;’;
         put @3 ‘set excel_import;’;
      end;

   if type=‘NUM’ then put @3 ‘study_new=put(‘ name ‘,9.);’;
   else put @3 ‘study_new=’ name ‘;’;
   if eof then
 put ‘run;’;
run;

%include stud;
filename stud;

Le code sauvegardé dans le fichier TMP_STUD.SAS se présente donc ainsi, vu que la variable STUDY est de type caractère.

data study_new;
   set excel_import;
   study_new=STUDY ;
run;

L’instruction %INCLUDE permet l’exécution de ce code.

h1

Il était une fois la LOG

juin 23, 2008

La fenêtre LOG (ou JOURNAL pour la version française de SAS) contient des informations plus ou moins détaillées sur le travail effectué par SAS. Ces informations peuvent être sauvegardées dans un fichier externe ou être supprimées lors de l’exécution du programme.

1. Une LOG plus ou moins détaillée

Deux situations se présentent :

  • lire les détails de l’exécution d’une macro
  • accéder aux détails d’un fichier .sas inclus dans un autre programme (%INCLUDE…)

Changer les options par défauts : les options MPRINT, MLOGIC et SYMBOLGEN s’adresse à la macro et SOURCE2 au programme inclus. Par défaut, ces options sont désactivées. Elles ont pour but d’aider le programmeur au stade du développement.

Voir le statut actuel des options : pour connaître l’état actuel d’une de ces options, il faut consulter la log après avoir exécuté la procédure options.

proc options;
run;

Remettre les options dans leur état initial : pour désactiver ces options, on utilise NOMPRINT, NOMLOGIC, NOSYMBOLGEN et NOSOURCE2.

Exemple, partie 1 : Le fichier main_include.sas contient l’instruction OPTIONS, le format AGE et la macro RAPPORT.

options source2 mprint mlogic symbolgen;

proc format;
   value age
   11-13 = ’11-13′
   14-16 = ’14-16′
   other = ‘Autre’;
run;

%macro rapport (dsn=);
proc report data=&dsn;
   columns name age sex;
   define name /‘Nom’ display;
   define age  /‘Age’ display ;
   define sex  /‘Sexe’ display;
   format age age.;
run;
%mend rapport;

Exemple, partie 2 : Dans un second programme, le premier programme et la macro RAPPORT sont appelés.

%include ‘C:/sasref/main_include.sas’;
%rapport (dsn=sashelp.class);

2. Commander la suppression du contenu de la LOG

Sous Windows, par défaut, à chaque nouvelle exécution d’un programme, la log grossie. Pour la vider, il y a deux possibilités : une manuelle et une automatique.

Après avoir activé la fenêtre log en la sélectionnant, il y a trois choix possibles :

  • Combiner les touches clavier Ctrl et E (raccourci clavier CTRL+E)
  • Sélectionner menu Edit/Clear All.
  • Taper la commande log;clear; dans le cadre en haut à gauche de l’écran

Cela marche aussi avec les fenêtres OUTPUT et EDITOR. Remplacez seulement le mot LOG par OUTPUT ou EDITOR pour la commande.

Pour une action automatique, l’instruction DM permet d’inclure dans le programme les mots-clés donné jusqu’à présent dans le cadre pour les commandes.

proc print data=sashelp.class;
run;

dm ‘log;clear;’;

3. Sauvegarder le contenu de la LOG dans un fichier externe

Rediriger le contenu de la log : la procédure PROC PRINTTO permet de rediriger le contenu de la log dans un fichier externe. Pour cela, le nom du fichier à créer et son chemin d’accès sont définis dans LOG=. Au choix, l’extension du fichier est .log ou .txt.

Rediriger le listing : le contenu de la fenêtre OUTPUT peut-être aussi redirigé. Cette fois-ci, il faut utiliser FILE=.

Ecraser les anciens fichiers : pour effacer le contenu d’un précédent fichier, il y a l’option NEW dans l’instruction PROC PRINTTO.

Réinitialisation : pour réactiver les destinations par défaut, la procédure sans argument est soumise à SAS.

proc printto log=‘C:/sasref/class.log’ new;
run;

proc printto file=‘C:/sasref/class.txt’ new;
run;

proc print data=sashelp.class;
run;

proc printto;
run;