Archive for the ‘Les procédures’ Category

h1

SAS 9.2. : WARNING avec PROC SQL et l’option UNDO_POLICY=NONE

janvier 6, 2013

Depuis SAS 9.2, un nouveau WARNING apparaît dans la log quand le nom de la table SAS d’entrée est le même que le nom de la table SAS de sortie. Pour éviter ce message, l’option undo_policy=none est à ajouter dans l’instruction proc sql;. SAS support prévient néanmoins que l’usage du même nom en entrée et en sortie présente un risque et que l’option enlève l’avertissement mais pas le risque.

1. Le message dans la log

WARNING: CREATE TABLE statement recursively references the target table

 

2. Exemple

Ce code générerait le warning avec SAS 9.2 si l’option undo_policy=none n’était pas utilisée.

proc copy in=sashelp out=work;
   select class;
run;

proc sql undo_policy=none;
   create table class as 
   select name, age
   from class;
quit;

 

En savoir plus

h1

Aller-Retour entre dataset et catalogue de formats avec CNTLIN en CNTLOUT

décembre 29, 2012

Dans un précédent article, je parlais des deux méthodes pour créer des formats avec une procédure proc format, la première étant de taper toutes les values dans une instruction value, la seconde étant de stocker ces valeurs dans un data set et de les convertir en format avec l’option cntlin. Aujourd’hui, je souhaite revenir sur l’option CNTLIN et son pendant CNTLOUT pour passer d’un dataset à un format et pour passer d’un format à un dataset.

1. Créer une table SAS (dataset) type

Pour débuter créons un data set (table SAS) appelée POP avec 4 colonnes START, LABEL, TYPE et FMTNAME. Cette table contient les données pour deux formats : un format numérique et un format alphanumérique. Ces deux formats sont appelés GRP.

data pop;
length start $40 label $200 type $1 fmtname $32;
retain fmtane 'GRP' type 'N';
start='10';
label='Per Protocol';
output;
start='11';
label='Modified Per Protocol';
output;
start='20';
label='Intent-to-Treat';
output;
start='21';
label='Modified Intent-to-Treat';
output;
type='C';
start='PP';
label='Per Protocol';
output;
start='mPP';
label='Modified Per Protocol';
output;
start='ITT';
label='Intent-to-Treat';
output;
start='mITT';
label='Modified Intent-to-Treat';
output;
run;

S’il est possible de convertir de convertir le nombre 100 stocker dans une variable alphanumérique en numérique, il est impossible de convertir le mot ABC en numérique. Dans cet exemple on comprend mieux pour quoi START est toujours alphanumérique qu’il s’agisse dun format numérique ou alphanumérique.

2. Passer d’un dataset à un format catalog

A présent la procédure proc format convertit le data set en format catalogue. Le data set est situé dans la bibliothèque (library) WORK. Il n’y a pas besoin de préciser la bibliothèque de la table POP. Par défaut le format catalog s’appellera FORMATS et sera stocké dans la bibliothèque WORK. L’option LIB n’est pas utilisé.

proc format cntlin=pop;
run;

Ainsi le code au dessus est équivalent à :

proc format cntlin=work.pop lib=work.formats;
run;

Le code proposé ci-dessus est uniquement là pour faciliter la compréhension. Sauf besoin particulier, la version simplifiée doit suffire.

3. Passer d’un format catalog à un dataset

Dans un second temps, je vous propose de convertir ce format dans un autre dataset.

proc format cntlout=pop2; 
run;

Ainsi le code au dessus est équivalent à :

proc format cntout=work.pop2 lib=work.formats; 
run;

A vous de jouez avec les proc print et librairies pour voir la résultat.

4. Rappel sur le nom du format

Notez ici que le nom du format est au maximum long de 32 caractères en  SAS 9.1.3 / SAS 9.2  et limité à 8 caractères pour la version SAS 8.2. Pour être plus précis, on a 32 caractères pour un format numérique et 31 caractères pour un format alphanumérique en SAS 9.1.3 et SAS 9.2, SAS gardant un caractère pour le symbole dollar $. SAS 8.2 fonctionnait sur le même principe : 8 caractères pour un format numérique et 7 caractères pour un format alphanumérique. Si le nom du format était trop long en SAS 8.2, SAS le coupe à la longueur maximum. Ainsi les nom  ALPHABETA et ALPHABETI sont interprétés pas SAS 8.2 en FMTNAME=ALPHABET pour un format numérique.

Aller plus loin

h1

Deux exemples d’usage de la syntaxe de l’ODS : PROC PRINT et PROC REPORT

juin 26, 2011

Jusqu’à présent, j’ai présenté la syntaxe de l’ODS (Output Delivery System) de SAS avec la procédure PROC REPORT pour générer vos tableaux dans des fichiers .rtf (ODS RTF), .pdf (ODS PDF) ou en XML avec extension .xls (ODS TAGSETS.EXCELXP).

PROC PRINT se révèle dans les cas les plus simples aussi avantageux. Voici deux fichiers .pdf contenant la même table, une fois générée avec PROC REPORT et une fois avec PROC PRINT.

ods listing close;

*1. Exemple de l’ODS avec PROC REPORT;

ods pdf file=‘O:/sasref/exemple_report.pdf’;
proc report data=sashelp.class nowd;
columns sex age;
define sex / display style(column)=[cellwidth=2cm];
define age / display style(column)=[cellwidth=3cm];
run;
ods pdf close;

*2. Exemple de l’ODS avec PROC PRINT;

ods pdf file=‘O:/sasref/exemple_print.pdf’;
proc print data=sashelp.class nobs;
var sex / style(column)=[cellwidth=2cm];
var age / style(column)=[cellwidth=3cm];
run;
ods pdf close;

ods listing;

h1

SAS 9.2 et PROC SORT : Quel est l’effet de l’option – sortseq=ascii (numeric_collation=on) ?

avril 10, 2011

Recherchez l’effet de l’option SAS 9.2 de la procédure PROC SORT : sortseq=ascii (numeric_collation=on),  une option qui manquait vraiment pour le tri de variables alphanumérique.

Pour cela, il vous suffit d’exécuter l’exemple suivant.

data one;
length x $10;
input x $;
datalines;
1
10
A
a
b
B
20
2
;
run;

proc sort data=one
out=nooption;
by x;
run;

proc sort data=one
out=withoption
sortseq=ascii (numeric_collation=on);
by x;
run;

title ‘No option’;
proc print data=nooption;
run;

title ‘With option’;
proc print data=withoption;
run;

Lecture Complémentaire

  • Trier les données par ordre croissant et décroissant
  • Tout sur l’instruction BY
  • SAS Online Doc 9.2: The PROC SORT Procedure
  • h1

    Répéter la valeur d’une variable sur chaque page avec ODS RTF

    septembre 26, 2010

    Il y a un peu plus d’un mois, je vous parlais de l’option SPANROWS de PROC REPORT pour pouvoir répéter une valeur groupée sur chaque page du listing.

    Mais si vous devez créer un fichier .RTF et non un fichier .PDF ou si vous n’avez pas SAS 9.2, vous pouvez vous rabattre sur cette solution.

    Elle présente le seul inconvénient de séparer la table en table distincte à chaque nouvelle valeur du la variable groupée.

    Voici donc un exemple à tester par vous même.

    1. Le setting

    Par simple soucis de présentation, quelques instructions de paramétrage sont données.

    • Enlever le titre par défaut avec l’instruction TITLE.
    • Enlever la date et le numéro de page par défaut et alignez le résultat à gauche.
    • Créer un format caractère SEX où M réfère à Garçon et F à Fille.


    *——————————————–;
    * Setting;
    *——————————————–;

    title;
    options nodate nonumber nocenter;

    proc format;
    value $ sex ‘M’=‘Garçon’
    ‘F’=‘Fille’;
    run;

    2. Préparation des données

    Afin d’avoir assez de données le fichier CLASS est multiplié par 5. Les noms sauvegardés dans la variable NAME sont incrémentés d’un nombre.

    *——————————————–;
    * 2. Data Preparation;
    *——————————————–;

    data class;
    set sashelp.class;
    output;
    name=cats(name,’1′);
    output;
    name=cats(name,’2′);
    output;
    name=cats(name,’3′);
    output;
    name=cats(name,’4′);
    output;
    name=cats(name,’5′);
    output;
    run;

    3. Reporting;

    Vos données doivent être triées afin d’utiliser l’instruction BY dans PROC REPORT.

    L’option d’ODS RTF STARTPAGE=NEVER empêchera le passage à une nouvelle feuille à chaque nouvelle valeur de la variable SEX.

    Au moyen des options COMPUTE/ENDCOMP, il est possible de personnaliser le texte en début de chaque page. Un texte aligné à gauche est ajouté. Une ligne avant et une ligne après sont ajoutées pour faciliter la lisibilité du rapport. Ce texte est composé de « SEXE :  » suivi de la valeur formatée de la variable SEX.

    *——————————————–;
    * 3. Reporting;
    *——————————————–;

    proc sort data=class;
    by sex;
    run;

    *options nobyline;

    ods rtf file=’C:/…/test1.rtf’ startpage=never;
    proc report data=class;
    by sex;
    column sex name;
    define sex  / /*id*/ group noprint ;
    define name / display  ‘Nom’;

    compute before _page_ /style=[just=left] ;
    line ‘ ‘;
    line @1 ‘Sexe:’ @6 sex $sex. ;
    line ‘ ‘;
    endcomp;

    run;

    ods rtf close;

    h1

    Des options pour se débarrasser de WARNING de SAS 9.2

    août 18, 2010

    Avec SAS 9.1.3 et SAS9.2 de nouveaux warning apparaissent. En voici deux que vous pouvez faire disparaître dans le cas où ils ne reflètent pas un problème dans votre programme.

    1. Avec PROC SQL, je crée une nouvelle table du même nom que la table source.
    2. Dans un data set je réduis la longueur d’une variable

    1. Utiliser le même nom de data set en entré et en sortie avec PROC SQL

    Pour illustrer le sujet, je vais d’abord créer un data set appelé ONE avec deux variables X et Y.

    data one;
    x=‘A’;
    y=‘B’;
    run;

    Ensuite je vais créer avec PROC SQL un nouveau data set du même nom ONE qui ne contiendra que la variable X.

    proc sql;
    create table one as
    select x
    from one;
    quit;

    Le message dans la log ressemble à ceci:
    WARNING: This CREATE TABLE statement recursively reference the target table. A consequence of this is a possible data integrity problem.

    Pour ne plus avoir ce message dans la log, ajouter l’option UNDO_POLICY=NONE

    proc sql undo_policy=none;
    create table one as
    select x
    from one;
    quit;

    Ce cas existe depuis SAS 9.1.3.

    2. Réduire la longueur d’une variable dans une étape data

    Une solution pour changer la longueur d’une variable est de définir sa longueur dans une instruction LENGTH avant de lire les données avec un SET par exemple.

    Depuis SAS 9.2, si la nouvelle longueur est plus petite que l’ancienne un WARNING apparaît dans la log. Ceci est une bonne chose car cela vous permet de repérer d’éventuelles coupures (truncations) de vos données.

    Dans certains cas cependant, vous savez pertinemment que le nombre de caractères dans données est au plus X et que dès lors elles ne seront pas coupées en réduisant la longueur.

    Vous pouvez vous épargner le warning en encadrant votre étape data des options globales VARLENCHK=nowarn et VALENCHK=warm.

    Je vous conseille d’appliquer cette option localement afin de pouvoir continuer à repérer d’autres coupures potentielles non prévues.

    data two;
    length x $32;
    x=‘A’;
    run;

    data two_a;
    length x $1;
    set two;
    run;

    WARNING : Multiple lengths were specified for the variable x by input data set(s). This may cause truncation of data.

    options varlenchk=nowarn;
    data two_b
    length x $1;
    set two;
    run;
    options varlenchk=warn;

    Notez cependant, qu’avec SAS 9.1.3 ou SAS 9.2, un warning apparaît dès lors que la variable est donnée dans une instruction BY. L’option VARLENCHK de SAS 9.2 ne vous enlèvera pas le warning. Je vous conseille donc de changer votre longueur au préalable si vous ne voulez pas ce WARNING.

    data two_b;
    length x $1;
    set two;
    by x;
    run;

    WARNING: Multiple lengths were specified for the BY variable x by input data sets and LENGTH, FORMAT, INFORMAT statements. This may cause unexpected results.

    Lectures complémentaires :

    h1

    Une option SAS 9.2 pour ODS PDF : répéter une valeur groupée sur plusieurs pages

    août 3, 2010

    Lorsque vous construisez un listing avec ODS PDF et PROC REPORT l’option GROUP de l’instruction DEFINE sert à n’afficher chaque valeur de la variable concernée qu’une seule fois.

    Hors, si cette valeur s’applique aux observations de plusieurs pages, elle ne sera pas répétée à moins d’ajouter l’option SPANROWS nouvelle avec SAS 9.2.

    Cette options ne fonctionne pas actuellement avec ODS RTF.

    Voici un exemple pour tester par vous même.

    1. Le setting

    Par simple soucis de présentation, quelques instructions de paramétrage sont données.

    • Enlever le titre par défaut avec l’instruction TITLE.
    • Enlever la date et le numéro de page par défaut et alignez le résultat à gauche.
    • Créer un format caractère SEX où M réfère à Garçon et F à Fille.


    *——————————————–;
    * Setting;
    *——————————————–;

    title;
    options nodate nonumber nocenter;

    proc format;
    value $ sex ‘M’=‘Garçon’
    ‘F’=‘Fille’;
    run;

    2. Préparation des données

    Afin d’avoir assez de données le fichier CLASS est multiplié par 5. Les noms sauvegardés dans la variable NAME sont incrémentés d’un nombre.

    *——————————————–;
    * 2. Data Preparation;
    *——————————————–;

    data class;
    set sashelp.class;
    output;
    name=cats(name,’1′);
    output;
    name=cats(name,’2′);
    output;
    name=cats(name,’3′);
    output;
    name=cats(name,’4′);
    output;
    name=cats(name,’5′);
    output;
    run;

    3. Reporting

    Enfin la section qui nous intéresse vraiment : générer un fichier .RTF et un fichier .PDF avec l’option SPANROWS et voir que que seul ODS RTF tient compte de cette option pour répéter l’observation en début de chaque nouvelle page.


    *——————————————–;
    * 3. Reporting;
    *——————————————–;

    ods listing close;
    ods rtf file=‘C:\sasref\test1.rtf’;
    ods pdf file=‘C:\sasref\test1.pdf’;


    proc report data=class spanrows nowd;
    column sex name;
    define sex / group ‘Sexe’;
    define name / display ‘Nom’ ;
    run;


    ods pdf close;
    ods rtf close;
    ods listing;

    h1

    Passer d’un format A4 à un format LETTRE

    mars 1, 2010

    Vous voulez imprimer les fichiers RTF générés avec ODS RTF dans une autre forme que le format A4. Quelle option utiliser pour utiliser un autre format standard comme le format LETTRE ? Comment personnaliser la zone d’impression et gérer les marges en conséquences ?

    1. Par défaut, le papier est au format A4 (21cm/29,7cm)

    ods listing close;
    ods rtf file=‘C:/sasref/margin_example.rtf’;
    proc print data=sashelp.class;
    run;
    ods rtf close;
    ods listing;

    2. Changer la taille du papier pour l’impression pour une lettre (21,59cm/27,94cm)

    options papersize=letter;

    ods listing close;
    ods rtf file=‘C:/sasref/margin_example.rtf’;
    proc print data=sashelp.class;
    run;
    ods rtf close;
    ods listing;

    3. Personnaliser la taille (21cm/27,94cm)

    Afin de personnaliser les marges dans l’instruction globale OPTIONS, je choisi ici d’enlever toute valeur au niveau du template (undefine margin). Ensuite ce template TEST_PAPERSIZE est appelé dans l’instruction ODS RTF.

    proc template;
    Define Style style.test_papersize;
    parent=styles.rtf;
    style Body from Body /
    leftmargin=_undef_
    right margin=_undef_
    topmargin=_undef_
    bottommargin=_undef_;
    End;
    run;

    De la taille du papier, il faut enlever les marges. Ici, nous voulons un papier avec une largeur de 21cm et une hauteur de 27,94cm. Les marges étant de 2 centimètres de chaque côté, on enlève 4 cm à la hauteur et 4 cm à la largeur définie par l’option PAPERSIZE.

    Les paramètres de l’option PAPERSIZE :

    1. Le 1er paramètre : la largeur
    2. Le 2ème paramètre : la hauteur

    options papersize=(’17cm’,‘23.94cm’) leftmargin=2cm rightmargin=2cm topmargin=2cm bottommargin=2cm;

    ods listing close;
    ods rtf file=‘C:/sasref/margin_example.rtf’ style=test_papersize;
    proc print data=sashelp.class;
    run;
    ods rtf close;
    ods listing;

    Note : j’ai obtenu le résultat escompté avec Word 2003 mais pas avec Word 2007. Vous pouvez apporter un commentaire avec votre expérience sur le sujet.

    h1

    Sauvegarder le résultat d’une comparaison de deux data sets dans un data set avec PROC COMPARE

    janvier 7, 2010

    Fréquemment, le programmeur est amené à comparer deux datasets. Deux méthodes s’offrent à lui : un merge accompagné de l’option IN ou la procédure PROC COMPARE. Voici une illustration de PROC COMPARE.

    1. Préparer les données

    Pour illustrer la procédure PROC COMPARE, il nous faut deux data sets. Le premier s’intitule CLASS et est sauvegardé dans la bibliothèque SASHELP (SASHELP.CLASS). Le second s’appelle également CLASS. C’est un dérivé du premier. Il est savegardé dans la bibliothèque temporarire WORK (WORK.CLASS).

    Voici comment est créé le second data set à partir du premier :

    • Une observation de la variable NAME passe de Alice à Alica
    • Une observation de la variable AGE prend la valeur 16 quand le nom est Robert
    • Une observation est ajoutée. La variable NAME prend la valeur Extra. Les autres variables ont des valeurs manquantes.

    data class;
    set sashelp.class;
    if name=‘Alice’ then name=‘Alica’;
    if name=‘Robert’ then age=16;
    output;
    if _N_=1 then
    do
    ;
    name=‘Extra’;
    output;
    end;
    run;

    2. L’importance d’avoir des données triées

    Dans la procédure PROC COMPARE utiliser par la suite, j’ai choisi d’utiliser l’instruction ID. Cette instruction requiert que les données soient triées préalablement. En effet, si ce n’est pas le cas un message d’erreur comme celui-ci apparaît :

    proc sort data=class;
    by name;
    run;

    3. Enregistrer le résultat de la différence dans un data set

    Ce qui m’intéresse ici est de sauvegarder le résultat de la comparaison dans un data set et non de l’afficher dans la sortie .txt. Pour ce faire, l’option OUT= précise le nom du data set qui sauvergardera les résultat et l’option NOPRINT stoppe l’affichage des résultats dans la log.

    Quatres options précisent le contenu du résultat :

    • OUTNOEQUAL : seules les observations où une différence est détectée seront sauvegardés
    • OUTBASE : une ligne contiendra les lignes d’observation du fichier de base défini dans l’option DATA=
    • OUTCOMP : une ligne contiendra les lignes d’observation du fichier de comparaison indiqué avec l’option COMPARE=
    • OUTDIF: une ligne annotera les valeurs présentant des différences

    En outre, l’instruction ID me permet de lister ma/mes variables que je considère comme des variables clés et d’en tenir compte dans la comparaison. J’ai choisi de comparer les observations seulement si elles ont la même valeur dans la variable NAME. Si une valeur de NAME n’est présente que dans un des deux fichiers, cette inconsistence sera également enregistrée.

    proc compare data=sashelp.class compare=class
    out=diff_class outnoequal outbase outcomp outdif
    noprint;
    id name;
    run;

    4. A quoi ressemble le fichier contenant les différences

    Voici le contenu du fichier DIFF_CLASS répertoriant les les différences entre le fichier SASHELP.CLASS et le fichier WORK.CLASS.

    options ls=max nocenter;
    proc print data=diff_class width=min;
    format _all_;
    run;

    Deux points sont à noter ici.

    Tout d’abord, on a trois cas où la valeur de la variable définie dans ID est présente dans un seul des deux fichiers. Dans chacun de ces trois cas, le fichier DIFF_CLASS enregistre une seule ligne d’observations.

    • NAME=Alica est seulement présent dans le fichier de comparaison (WORK.CLASS)
    • NAME=Alice est seulement présent dans le fichier de base (SASHELP.CLASS)
    • COMPARE=Extra est seulement présent dans le fichier de comparaison (WORK.CLASS)

    Puis, on a un cas où NAME=Robert est présent dans les deux fichiers mais avec des différences dans les autres variables. Une troisième ligne DIF précise où les différences et les égalités se situent.

    • Valeurs numériques
      • E pour égalités : c’est le cas des variables HEIGHT et WEIGHT
      • un nombre qui mesure la différence :  l’âge dans WORK.CLASS et de 4 plus grand que celui dans le fichier de base SASHELP.CLASS
    • Valeurs caractères
      • Un point pour des égalités : la variable SEX
      • Des xxx pour une différence : le cas ne se présente pas dans notre exemple

    5. Un fichier est créé même si aucune différence n’est enregistrée

    Il n’existe pas d’options dans PROC COMPARE pour ne créer un fichier que si au moins une différence entre les fichiers est trouvée.

    proc compare data=sashelp.class compare=sashelp.class;
    out=nodiff outnoequal outbase outcomp outdif
    noprint;
    id name;
    run;

    Vous devrez donc ensuite compléter votre programme à la suite de PROC COMPARE pour supprimer ces fichiers si c’est ce que vous avez besoin.

    h1

    Afficher toutes les valeurs possibles d’une variable définies dans un format avec PRELOADFMT option (PROC TABULATE)

    décembre 2, 2009

    Vous pouvez avoir besoin de réaliser un tableau comptant le nombre d’observations par catégories. Deux possibilités s’offrent à vous :
    afficher le nombre d’observations parmi les catégories présentent dans vos données ou
    afficher le nombre d’observations pour toutes les catégories possibles et imaginables définies dans un format. Les catégories non présentent dans les données ont alors une fréquence de zéro.

    Par défaut, seules les catégories présentent dans les données seront retenues par PROC TABULATE.
    Voici comment utiliser les options PRELOADFMT ORDER= et PRINTMISS pour prendre en compte tous les valeurs possibles et non seulement celles observées.

    1. Préparer les données

    Dans un premier temps, un format caractère $SEX est créé. Il prend trois valeurs possibles, M pour les hommes (male), F pour les femmes (female), et pour tout autre caractère, le label sera Missing.

    proc format;
    value $ sex ‘M’=‘Male’
    ‘F’=‘Female’
    other=‘Missing’;
    run;

    2. Compter le nombre de garçons et de filles ayant une donnée pour l’âge.

    Ici, on note que 10 garçons et 9 filles ont une donnée sur l’âge. Notez que la statistique n se limite aux valeurs non manquantes, sur le même principe que la fonction n. Si un âge est manquant, il ne sera pas inclus avec cette statistique mais avec la statistique nmiss.

    proc tabulate data=sashelp.class;
    class sex;
    var age;
    table sex=‘ ‘,age=‘ ‘*n=‘Freq’*f=5.;
    format sex $sex.;
    run;

    A présent ce qui nous intéresse est d’afficher toutes les catégories possibles pour la variable SEX, comme définies dans le format $SEX.

    Dans l’instruction CLASS, il faudra ajouter l’option /PRELOADFMT order=data.
    Tandis que dans l’instruction TABLE, il faudra noter l’option PRINTMISS.

    A la place de ORDER=DATA, vous pouvez mettre ORDER=FORMATTED, ORDER=UNFORMATTED ou encore ORDER=FREQ.

    proc tabulate data=sashelp.class;
    class sex/preloadfmt order=data;
    var age;
    table sex=‘ ‘,age=‘ ‘*n=‘Freq’*f=5./printmiss;
    format sex $sex.;
    run;

    3. Calculer l’âge moyen des garçons et des filles

    L’âge sera calculer en se servant des valeurs non manquantes.

    L’âge moyen sera manquant (représenté par un point) pour les catégories de SEX où aucun âge n’est disponible. Vous pouvez remplacer ce point par un zéro via l’instruction TABLE au moyen de l’option /MISSTEXT=’0′.

    Avant sans MISSTEXT=’0′

    proc tabulate data=class;
    class sex/preloadfmt order=data;
    var age;
    table sex=‘ ‘,age=‘ ‘*mean=‘Mean Age’*f=5./printmiss;
    format sex $sex.;
    run;

    Après avec MISSTEXT=’0′

    proc tabulate data=class;
    class sex/preloadfmt order=data;
    var age;
    table sex=‘ ‘,age=‘ ‘*mean=‘Mean Age’*f=5./printmiss misstext=’0′;
    format sex $sex.;
    run;

    h1

    Lire le contenu d’un catalogue pour macros

    septembre 24, 2009

    Dans l’article « Sauvegarder une macro au delà d’une session« , vous avez vu comment créer un macro catalogue permanent. Ici, je vous propose de voir comment savoir quelles macros sont contenues dans ce fichier.

    1. Rappel : ajouter une entrée dans un catalogue pour macros

    Dans l’étape qui suit, la macro PERM_MACRO a été sauvée dans un catalogue pour macro. Le nom par défaut d’un catalogue pour macro est SASMACR. Celui-ci a été sauvegardé dans la bibliothèque SASREF.

    libname sasref ‘C:/sasref’;

    options sasmstore=sasref mstored;

    %macro perm_macro /store;
    proc print data=sashelp.class;
    run;
    %mend perm_macro;

    2. Voir le contenu d’un catalogue pour macro

    A présent, la procédure catalogue et plus particulièrement l’instruction CONTENTS permet de lire le contenu de SASMACR.

    La procédure CATALOG  peut être composée de plusieurs étapes. Pour voir le résultat en séquence de ces étapes une instruction RUN est ajoutée entre chacune d’elle. Un QUIT en fin de procédure permet de clore la procédure.

    Ici comme une seule étape est requise, seul un RUN apparaît. Il est donc possible, dans ce cas précis de se contenter d’un QUIT.

    • Avec RUN et QUIT, REAL et CPU times sont de 0.01 secondes.
    • Avec seulement QUIT, REAL TIME=0.04 secondes et CPU TIME=0.00 secondes.

    libname sasref ‘C:/sasref’;

    proc catalog catalog=sasref.sasmacr;
    contents;
    run;
    quit;

    Ce contenu est affiché dans la fenêtre OUTPUT de SAS. Voir le résultat :

    content_macro_catalog

    Lectures complémentaires

    h1

    Passer par un format pour changer les couleurs d’une cellule dans un tableau (PROC REPORT et ODS)

    septembre 17, 2009

    Dans de précédents articles, je vous ai parlé de la possibilité de changer le style des cellules d’un tableau. Je vous invite ici à découvrir comment un format peut vous éviter de passer par un COMPUTE/ENDCOMP de PROC REPORT pour changer le style selon les valeurs prises par une variable donnée.

    1. Créer les formats pour l’exemple

    Pour mettre en gras (bold) ou non, il faut passer par le style FONT_WEIGHT. Dans notre exemple, ce style prendra la valeur BOLD quand la variable AGE aura des valeurs entre 14 et 16 ans et un LIGHT pour un style non gras. Vous avez aussi à disposition la valeur MEDIUM pour un ton légèrement plus prononcé.

    Pour changer la couleur du texte, c’est le style FOREGROUND qu’il faut utiliser. Dans notre cas, le texte aura la couleur bleu si la variable AGE est comprise entre 14 et 16 ans inclus.

    proc format;
    value age_font 1113=‘light’
    1416=‘bold’;
    value age_color 1416=‘blue’;
    run;

    2. Utiliser le format dans PROC REPORT

    Pour changer le style d’une colonne en particulier, il suffit d’ajouter style(column)=[…] dans l’instruction DEFINE.

    Ici au lieu de donner une couleur à toutes les valeurs avec FOREGROUND= suivi du nom de la couleur, on donne le format AGE_COLOR. qui prendra la valeur BLUE pour les AGE des 14-16 ans.

    De manière similaire, l’épaisseur du trait est changée avec FONT_WEIGHT et le format AGE_FONT. défini auparavant.

    ods listing close;
    ods pdf file=‘C:/sasref/zebre.pdf’;
    proc report data=sashelp.class nowd;
    columns name age;
    define name / display ;
    define age / display style(column)=[font_weight=age_font. foreground=age_color.];
    run;
    ods pdf close;
    ods listing;

    3. Voir le résultat

    color_format

    Lectures complémentaires

     

    h1

    Alterner les couleurs de fond dans un tableau : une ligne sur deux (ODS et PROC REPORT)

    août 30, 2009

    Ces semaines passées, je vous ai proposé une syntaxe pour changer le style des cellules d’un tableau généré sous SAS avec PROC REPORT. Aujourd’hui, je vous propose une variante permettant de changer la couleur de fond une ligne sur deux. L’exemple utilise une sortie PDF. Le programme peut s’appliquer aux sorties RTF et TAGSETS.EXCELXP.

    1. Le programme

    Dans PROC REPORT, l’instruction CALL DEFINE contenu entre les instructions COMPUTE et ENDCOMP permet de modifier le style des lignes dans un tableau.

    La notion de RETAIN : Dans l’exemple qui suit une variable nommée CNT est créée avec un RETAIN implicite. Le changement de couleur de fond est fonction de la valeur prise par cette variable. Vous pouvez également utilisée une variable déjà existante dans le data set lu.

    La foncton MOD() : Le modulo est le résidu d’une division. La fonction MOD() avec un modulo 2 permet de distinguer les valeurs pairs des valeurs impaires. Ici à chaque fois que la valeur CNT a une valeur pair, le fond est mis en gris.

    ods listing close;
    ods pdf file=‘C:/sasref/zebre.pdf’;
    proc report data=sashelp.class nowd;
    columns name age;
    define name / display;
    define age / display;
    compute name;
    cnt+1;
    if mod(cnt,2) then call define (_row_,‘style’,‘style=[background=lightgrey]’);
    endcomp;
    run;
    ods pdf close;
    ods listing;

    2. Le résultat

    zebre

    Lectures complémentaires

    h1

    Le va-et-vient avec un fichier de transport

    août 11, 2009

    L’envoi de fichiers AS par email peut se faire au moyen de fichiers « compressés » appelés fichiers de transport (transport files). Ces fichiers ont une extension .xpt. Dans cet article, vous verrez deux choses :

    • Comment créer un fichier .xpt
    • Comment extraire les données d’un fichier .xpt

    1. Créer un fichier .xpt avec la procédure CPORT

    Dans l’exemple ci-dessous, la table CLASS de la bibliothèque SASHELP est ajoutée dans le fichier de transport SASHELP_CLASS.XPT.

    filename tranfile ‘C:/sasref/transport_files/sashelp_class.xpt’;
    proc cport lib=sashelp file=tranfile memtype=data;
    select class;
    run;

    Quels fichiers envoyer ?

    • LIB= : Pour ce faire, il faut préciser le nom de la bibliothèque contenant les fichiers à traiter avec LIB= : Si aucune bibliothèque n’est précisée, c’est la bibliothèque WORK qui est consultée.
    • SELECT : les fichiers SAS à ajouter sont listés dans l’instruction SELECT. Si aucune instruction SELECT n’est fournie, tous les fichiers sont copiés.
    • MEMTYPE= : L’option MEMTYPE restreint la sélection des fichiers aux tables SAS. Ainsi deux fichiers CLASS sont présents dans la bibliothèque SASHELP (une vue et une table) alors seule la table sera utilisée.

    Où sauvegarder les données ? Le nom et la destination du fichier de transport sont définis dans une instruction FILENAME. Cette référence au fichier, nommée TRANFILE, est ensuite appelé par FILE=.

    xpt

    2. Extraire les données d’un fichier .xpt avec la procédure CIMPORT

    Dans l’exemple qui suit, les données du fichier transport SASHELP_CLASS.XPT sont extraites et sauvegardées dans la bibliothèque EXTRACT.

    libname extract ‘C:/sasref/extracted_files’;
    filename sasref ‘C:/sasref/transport_files/sashelp_class.xpt’;
    proc cimport lib=extract infile=sasref;
    run;

    Pour extraire les fichiers d’un fichier de transport, il y a l’option la procédure PROT CIMPORT.

    Quelle destination ? L’option LIB= précise la bibliothèque de destination des fichiers contenus dans le fichier de transport.

    Quelle source ? L’option INFILE= indique le nom et le chemin d’accès au fichier de transport.

    xpt_extracted

    Lectures complémentaires

    Articles du blog

    h1

    Changer la couleur d’une ligne ou d’une colonne via PROC REPORT et ODS

    juillet 30, 2009

    Après vous avoir présenter comment changer la couleur d’une cellule dans un fichier .xls, je vous propose de voir comment changer la couleur de toute une colonne ou de toute une ligne avec PROC REPORT et ODS TAGSETS.EXCELXP. Cela est intéressant pour distinguer votre ligne/colonne TOTAL du reste de vos données. Notez que la syntaxe s’applique également avec ODS RTF et ODS PDF par exemple.

    1. Changer le style de couleur pour une colonne

    Pour changer la couleur d’une colonne, on utilisera STYLE(COLUMN)=[] dans l’instruction DEFINE de son choix.

    Pour changer la couleur d’une ligne, il faudra passer par COMPUTE/ENDCOMP et CALL DEFINE. Pour changer la couleur d’une celulle, nous avions dans le précédent article utiliser _COL_ comme premier argument. Pour appliquer la couleur à toute la ligne, il suffira de remplacer ce premier argument par _ROW_.

    ods listing close;
    ods tagsets.excelxp file=‘C:/sasref/col_row_color.xls’;

    proc report data=sashelp.class nowd;
    column name age;
    define name / ‘Nom’ display style(column)=[background=lightblue];
    define age / ‘Age’ display;
    compute age;
    if age=15 then call define (_ROW_,‘style’,‘style=[background=lightblue foreground=red ]’);
    endcomp;
    run;

    ods tagsets.excelxp close;
    ods listing;

    Dans l’exemple ci-dessus la colonne Nom est mise en bleu clair. Les lignes où l’âge est égal à 15 ans sont mises en bleu clair également et le texte est mis en rouge.

    2. Voir le résultat

    xls_color_row_column

    Lectures complémentaires

    h1

    Un moyen simple de changer les couleurs en fonction des valeurs prises par des variables dans un fichier .xls

    juillet 26, 2009

    Suite à la question de Pierre, je vous invite à découvrir comment changer la couleur de données selon leur valeurs dans un fichier .xls généré au moyen d’ODS TAGSETS.EXCELXP et PROC REPORT.

    1. Le code de base à améliorer

    ODS TAGSETS.EXCELXP FILE=’…xls ‘ / ODS TAGSET.EXCELXP CLOSE : Pour l’exemple, un fichier CLASS_COLOR.XLS est créé.

    PROC REPORT : Il contient les données de la variable AGE disponibles dans la table SASHELP.CLASS.

    ODS LISTING CLOSE/ODS LISTING : Aucune sortie n’est envoyée vers la destination traditionnelle LISTING le temps de la création du fichier .xls.

    ods listing close;
    ods tagsets.excelxp file=‘C:/sasref/class_color.xls’;
    proc report data=sashelp.class nowd;
    column age;
    define age / ‘Age’ display;
    run;
    ods tagsets.excelxp close;
    ods listing;

    2. L’ajout de COMPUTE dans PROC REPORT

    A présent les intructions COMPUTE et ENDCOMP englobe une condition. Si la variable AGE est égale à 15 alors tous la valeur 15 est mise en rouge (foreground=) et la couleur de fond de la cellule est bleu clair (background=).

    Pour cela, on utilise CALL DEFINE si et seulement si AGE=15. CALL DEFINE est composé de trois paramètres :

    • _COL_
    • ‘style’
    • ‘style=[à compléter]’

    ods listing close;
    ods tagsets.excelxp file=‘C:/sasref/class_color.xls’;
    proc report data=sashelp.class nowd;
    column age;
    define age / ‘Age’ display;
    compute age;
    if age=15 then call define (_COL_,‘style’,‘style=[background=lightblue foreground=red]’);
    endcomp;
    run;
    ods tagsets.excelxp close;
    ods listing;

    3. Voir le résultat

    xls_compute

    4. Quelques styles supplémentaires

    Pour compléter la liste des styles, vous avez par exemple:

    • Changer la taille des caractères : font_size=14pt (mettre en taille 14 points)
    • Changer l’inclinaison des caractères : font_style=italic (mettre en italique)
    • Changer l’épaisseur des traits formant les caractères : font_weight=bold  (mettre en gras)
    • Changer la police de caractères : font_face= »Courier New, Arial » (utiliser Courier New si disponible, sinon utiliser Arial).

    Lectures complémentaires :

    h1

    Personnaliser l’apparence des titres et pieds-de-page dans un fichier.xls (ODS TAGSETS.EXCELXP et PROC TEMPLATE)

    juillet 14, 2009

    Après vous avoir présenté les options EMBEDDED_TITLES et EMBEDDED_FOOTNOTES dans l’article : Ajouter les titres et pieds-de-page dans une feuille de calcul du fichier .xls, je vous propose de personnaliser l’apparence de vos titres au moyen d’un nouveau style créé dans une instruction PROC TEMPLATE.

    1. Créer un style personnaliser pour ses titres et pieds de page

    Le nouveau style s’appelle XLS_TITL. Comme base, nous prenons un style existant sous SAS : STYLES.DEFAULT et faisont quelques modification au niveau des titres et pieds-de-page.

    proc template;
    define style styles.xls_titl;
    parent=styles.rtf;

    style systemtitle from systemtitle /
    background=transparent
    foreground=#000000
    font_style=roman
    font_weight = medium
    font_size=18pt
    font_face=‘Arial’;

    style systemfooter from systemfooter/
    background=transparent
    foreground=#000000
    font_style=roman
    font_weight = medium
    font_size=14pt
    font_face=‘Arial’;

    end;
    run;

    • BACKGROUND modifie la couleur de font des cellules (voir l’article : choisir ses couleurs sous SAS). Notez que le mot TRANSPARENT ne fonctionne pas avec la version 1.86 de TAGSETS.EXCELXP mais avec certaines versions plus anciennes. Mettre à jour ses TAGSETS pour EXCELXP »
    • FOREGROUND modifie la couleur du texte
    • FONT_STYLE empêche l’inclinaison par défaut (enlever l’italique : roman, mettre en italic : italic)
    • FONT_WEIGHT enlève la côté gras présent par défaut (enlever les gras : medium, mettre en gras : bold)
    • FONT_SIZE défini la taille des caractères
    • FONT_FACE liste les polices à utiliser. Si plusieurs polices sont listées entre guillemets, la première disponible sur l’ordinateur sera retenue.

    2. Appeler le style dans l’instruction ODS TAGSETS.EXCELXP

    L’option STYLE= a été ajouté dans la première instruction ODS TAGSETS.EXCELXP . Elle est suivie du nom du style créé préalablement. Cela donne STYLE=XLS_TITL.

    ods listing close;
    ods tagsets.excelxp file=‘C:/sasref/class.xls’ style=xls_titl
    options(embedded_titles=‘yes’
    embedded_footnotes=‘yes’);

    title ‘Titre’;
    footnote ‘Pied’;
    ods tagsets.excelxp;

    proc report data=sashelp.class nowd;
    columns name age;
    define name/display ‘Nom’;
    define age /display ‘Age’;
    run;

    ods tagsets.excelxp close;
    ods listing;

    Pour le reste des explications concernant cette syntaxe, reportez-vous à l’article de la semaine dernière.

    3. Voir le résultat

    02_xls_title

    Lectures complémentaires :

    h1

    Deux manières de créer un data set vide

    juillet 2, 2009

    Dans un précédent article Copier la structure d’un data set et se séparer des données, nous avons vu comment récupérer la structure d’une table (data set) de référence, c’est-à-dire copier les caractéristiques des variables sans les données. Ici, vous verrez comment créer un data set, appelé EMPTY, sans données et sans se baser sur un data set de référence.

    L’intérêt est de souvent de pouvoir ensuite empiler des data sets ayant des longueurs de variables. En effet la longueur d’une variable rencontrée dans le premier data set sera la longueur de référence. Il ne faut pas qu’elle soit plus petite que celle du data set suivant. Autrement le texte des observations d’après est coupé (truncated).

    1. Avec une étape data

    Au choix, vous avez l’instruction ATTRIB ou les différentes instructions LABEL, LENGTH, FORMAT, INFORMAT pour créer les variables du data set.

    data empty;
    attrib var_text   label=‘Var. caractère, longueur 20’ length=$20
    var_num_dt label=‘Var. numérique, longueur 8’ format=date9.;
    stop;
    run;

    Dans la log, SAS précisera qu’aucune valeur n’a été donné aux variables VAR_TEXT et VAR_NUM_DT.

    NOTE: Variable var_text is uninitialized.
    NOTE: Variable var_num_dt is uninitialized.

    2. Créer un data set vide avec la procédure SQL

    La procédure SQL

    proc sql;
    create table empty
    (
    var_text char(20) label=‘Var. caractère, longueur 20’ ,
    var_num_dt num label=‘Var. numérique, longueur 8’ format=date9.
    );
    quit;

    3. Voir le résultat

    J’ai choisi d’ajouter l’option VARNUM à la procédure PROC CONTENTS pour afficher les données dans l’ordre

    proc contents data=empty varnum;
    run;

    La variable VAR_TEXT apparaît en premier. Il s’agit d’une variable alphanumérique de longueur 20 sans format et ayant pour libellé : Var. caractère, longueur 20.

    La seconde variable VAR_NUM_DT est numérique, de longueur 8. Le format DATE9 est appliqué dessus de manière permanente. Le libellé de cette variable est : Var. numérique, longueur 8.

    The CONTENTS Procedure

    Variables in Creation Order

    # Variable   Type   Len Format Label

    1 var_text   Char   20         Var. caractère, longueur 20
    2 var_num_dt Num     8  DATE9. Var. numérique, longueur 8

    Lectures complémentaires

    h1

    Mettre à jour ses TAGSETS pour EXCELXP

    juin 4, 2009

    Créer un fichier XML ouvrable avec Excel est possible avec l’ODS TAGSETS.EXCELXP de SAS. Il est important de disposer des dernière mises à jour des tagsets de EXCELXP pour utiliser son potentiel. Quelle version utilisez-vous actuellement ? Comment faire la mise à jour ?

    1. Quelle version de TAGSETS.EXCELXP utilisez-vous ?

    Pour connaître la version de TAGSETS.EXCELXP que vous utilisez, consultez la log après avoir exécuté ce PROC TEMPLATE.

    proc template;
    source tagsets.excelxp;
    run;

    2.  Comment faire les mises à jour ?

    Allez sur la page http://support.sas.com/rnd/base/ods/odsmarkup/ pour trouver le code à exécuter dans SAS.

    Par exemple, pour la mise à jour 1.86 (15 avril 2008), copiez dans votre éditeur SAS le code http://support.sas.com/rnd/base/ods/odsmarkup/excltags.tpl et exécutez-le.

    En soumettant une nouvelle fois la procédure PROC TEMPLATE, la log nous indique que la version 1.86 est celle actuellement en place.

    tagsets_version_v1_86

    h1

    Les pièges d’Excel : Une colonne sans nom (GETNAME=YES)

    Mai 24, 2009

    Lors de l’importation d’un fichier Excel sous SAS au moyen de la procédure PROC IMPORT, la première ligne indique à SAS quel nom donné aux variables au lieu d’utiliser les lettres de l’alphabet. L’option par défaut est GETNAME=YES. Dans un cas, des informations peuvent être perdues. C’est ce que je vous propose de voir ici.

    1. Le cas où tout va bien

    Le tableau à importer contient 4 colonnes. La première ligne servira à SAS pour attribuer le nom des variables. La seconde ligne contient les données. Le tableau SAS aura 4 variables avec une observation chacune.

    La procédure PROC IMPORT

    proc import datafile=‘C:/sasref/getname_example1.xls’
    out=getname_ex
    dbms=xls
    replace;
    getname=yes;
    run;

    2. Un nom de colonne manquant

    Dans le cas suivant, une des cellules de la première ligne est vide. SAS cherche un nom (GETNAMES=YES) mais n’en trouve pas. SAS n’importe pas la colonne concernée.. Le data set contient alors 3 variables avec une observation chacune.