Posts Tagged ‘informatique’

h1

Les fonctions put et input – un sujet épineux

novembre 23, 2022

Découvrir le cours sur Udemy

Pour convertir une valeur du caractère au numérique et inversement, ou encore du caractère au caractère / du numérique au numérique, il est courant de passer par les fonctions put et input. Grâce à ces fonctions historiques et aux nouvelles fonctions putn, putc, inputn et inputc, il est possible de changer le type d’une variable, sélectionner des observations en fonction de valeurs formatées, de gagner en performance en évitant le tri imposé par un merge, d’afficher la date du jour dans un nom de fichier, dans un titre, et encore plus de chose.

Mais il y a des pièges. Comment s’assurer que les valeurs obtenues ne soient pas tronquées, ou encore pire, involontairement modifiées ? Comment repérer les valeurs présentent uniquement dans les formats mais pas dans les données ?

Dans ce cours, on part de la base afin de savoir choisir la bonne fonction et le bon format/informat en fonction de son besoin. À la fin de la première partie, vous saurez déjà comment convertir du caractère au numérique… En programmation, le diable se cache dans les détails. Dans la seconde partie, nous verrons tous ces cas particuliers qui font la richesse mais aussi la difficulté de ces fonctions. Les utilisateurs SAS débutants comme les programmeurs expérimentés y trouveront leur compte.

Le coupon de promotion pour le lancement de ce cours est valable jusqu’au 15 décembre 2022 : UPGRADE2022

et partager l’information à un ami ! Code promo : UPGRADE2022

h1

Protégé : Newsletter Exercices – n°1 : Solution

juillet 14, 2012

Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

h1

SAS 9.2 Souligner ou barrer un texte dans une table en sortie ODS

juillet 14, 2011

Avec SAS 9.2 il est maintenant possible de souligner/barrer des valeurs d’une table dans une sortie ODS et plus seulement dans le titre.

L’exemple est basé sur une sortie .pdf. TEXTDECORATION=UNDERLINE souligne les valeurs. TEXTDECORATION=LINE-THROUGH barre les valeurs et TEXTDECORATION=OVERLINE (usage très rare a priori) ajoute une ligne au dessus du texte.

ods listing close;
ods pdf file=‘c:/sasref’;
proc print data=sashelp.class;
var name / display style(column)=[textdecoration=underline];
var sex / display style(column)=[textdecoration=line-through];
var age / display style(column)=[textdecoration=overline];
run;
ods pdf close;
ods listing;

Lecture complémentaire

SUGI, pour visualiser le résultat : http://www2.sas.com/proceedings/sugi31/227-31.pdf

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

    Plusieurs formats pour une variable numériques – passer à une variable caractère avec la fonction PUTN

    octobre 14, 2010

    Découvrez le cours de novembre 2022 : Les fonctions put et input – un sujet épineux

    Dans cet article que vous propose une illustration de la fonction PUTN. En effet une variable numérique peut contenir des groupes de valeurs. Chaque groupe de valeurs se réfère à un format donnée. Le nom de ces formats est disponible dans une autre variable. La question est alors comment puis-je créer une variable caractère équivalent simplement, sans boucle, sans if-then, etc. La solution : la fonction PUTN. Voici un exemple pour illustrer le propos.

    1. Le problème en exemple

    Dans cet exemple, deux formats numériques AGE et SEX exitent.

    proc format;
    value age 11-13=’11-13′
    14-16=’14-16′;
    value sex 1=‘Male’
    2=‘Female’;
    run;

    Dans un data set, ONE, trois variables existent :

    • CRITERIA : les critères sont AGE et SEX dans l’exemple.
    • CODLST : le nom des formats qui expliquent les valeurs numériques sont enregistrés dans la variable CODLST.
    • VALN: les valeurs numériques associées aux critères sont disponibles dans la variable VALN.

    data one;
    length criteria $8 codlst $8;
    input criteria $ codlst $ valn;
    age age 12
    sex sex 1
    ;
    run;

    L’objectif est de créer une variable VALC qui contienne l’équivalent alphanumérique de VALN (la valeur donnée dans le label du format).

    2. La solution proposée : PUTN

    data two;
    set one;
    length valc $20;
    VALC=putn(valn,codlst);
    run;

    3. Le résultat attendu

    criteria codlst valn valc

    age      age    12   11-13
    sex      sex    1    Male

    Ici les formats sont tous numériques. La fonction PUTN est utilisée.
    Pour des formats alphanumériques, il faudra se servir de la fonction PUTC.

    Allez plus loin

    Découvrez le cours de novembre 2022 : Les fonctions put et input – un sujet épineux

    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

    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

    Protégé : Newsletter Exercice – n°1 : Enoncé

    juillet 6, 2010

    Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

    h1

    Macro : mini-programmes/routines pour tester la validité d’un nom de variable

    juin 27, 2010

    Après avoir appris les bases de la programmation, vous allez vous rendre compte que certaines tâches se répètent de programme à programme. Une partie d’entre eux peut se résumer à quelques lignes. Il est alors tentant d’écrire un programme de manière « officielle » et de le valider au lieux d’avoir à écrire le code à chaque fois.

    Voici un petit exemple. Il s’agit du descriptif d’une macro qui va indiquer si le nom de variable donné est conforme aux règles requises par SAS. Ici vous avez la spécification et les tests de validation.

    1. Spécification : Quelles sont les règles ?

    Le nom d’une variable ne peut pas avoir plus de 32 caractères.

    Le premier caractère est une des 26 lettres de l’alphabet ou un chiffre.

    Les autres caractères  peuvent être des lettres de l’alphabet, un chiffre ou un tiret bas (underscore).

    2. Spécification : Quelques contraintes ?

    Vous développez une macro disons VARNAME_VALID ayant un paramètre VARNAME où vous pourrez entrer le nom d’une variable à tester. Si ce nom entre dans les critères de définition de SAS, alors une macro variable varname_ok=1 sinon la macro variable varname_ok=o.

    3. Test Cases : Quand tout va bien: un nom de variable avec une seule lettre, deux lettre, commençant par un tiret bas, écrit en majuscule, avec un chiffre au milieu, avec un chiffre à la fin

    Qu’est ce qui est testé : un nom de variable suivant les règles requises par SAS.

    Quel est le code à soumettre :

    %varname_valid(varname=a);
    %varname_valid(varname=ab);
    %varname_valid(varname=_ab);
    %varname_valid(varname=AB);
    %varname_valid(varname=ab1a);
    %varname_valid(varname=ab1);

    Quel est le résultat attendu :

    La macro variable garde la valeur un

    &varname_ok.=1

    Un message dans la log est affiché :

    NOTE: (VARNAME_VALID) Nom de variable correct.
    NOTE: (VARNAME_VALID) Valeur actuelle :  ab

    D’autres programmes peuvent être appelés après.

    4. Test Cases : Violation des pré-requis de la macro

    4.1 Violation pré-requis : le paramètre est manquant

    Qu’est ce qui est testé : Un nom de variable doit être donné dans le paramètre de la macro

    Quel est le code à soumettre : %varname_valid(varname=);

    Quel est le résultat attendu :

    La macro variable VARNAME_OK prend la valeur zéro

    &varname_ok.=0

    Un message dans la log est affiché :

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle:
    EARNING: (VARNAME_VALID) Valeur attendue: un nom de variable.

    D’autres programmes peuvent être appelés après.

    4.2 Violation pré-requis : plus d’un nom de variable est entré

    Qu’est ce qui est testé : Plus d’une variable est entrée dans le paramètre de macro

    Quel est le code à soumettre : %varname_valid(varname= ab cd );

    Quel est le résultat attendu :

    La macro variable prend la valeur zéro

    &varname_ok.=0

    Un message dans la log est affiché :

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle : ab cd
    WARNING: (VARNAME_VALID) Valeur attendue : un seul nom de variable.

    D’autres programmes peuvent être appelés après.

    5. Test Cases : Les règles définies par SAS pour nommer une variable

    5.1  Un nom de variable : Au maximum 32 caractères

    Qu’est ce qui est testé : un variable avec plus de 32 caractères

    Quel est le code à soumettre : %varname_valid(varname=abcdefghijklmnopqrstuvwxyz1234567890);

    Quel est le résultat attendu :

    La macro variable prend la valeur z éro

    &varname_ok.=0

    Un message dans la log est affiché :

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle : abcdefghijklmnopqrstuvwxyz1234567890
    WARNING: (VARNAME_VALID) Valeur attendue : 32 caractères au maximum.

    D’autres programmes peuvent être appelés après.

    5.2 Un nom de variable : commence par une lettre de l’alphabet (a-z) ou un tiret bas

    Qu’est ce qui est testés : Un premier caractère différent d’une lettre de l’alphabet ou d’un tiret bas

    Quel est le code à soumettre : %varname_valid(varname=é);

    Quel est le résultat attendu :

    La macro variable prend la valeur zéro

    &varname_ok.=0

    Un message dans la log est affiché :

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle : é
    WARNING: (VARNAME_VALID) Valeur attendue : La première lettre est une des 26 lettres ou un tiret bas.

    D’autres programmes peuvent être appelés après.

    5.3 Un nom de variable : Après le premier caractère on peut avoir des lettres (a-z), des chiffres (0-9) et des tirets bas.

    Qu’est ce qui est testé : un caractère différent d’une lettre de l’alphabet, d’un chiffre ou d’un tiret bas parmi les autres caractères de l’alphabet

    Quel est le code à soumettre : %varname_valid(varname=1é);

    Quel est le résultat attendu :

    La macro variable prend la valeur zéro

    &varname_ok.=0

    Un message dans la log est affiché :

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle : 1é
    WARNING: (VARNAME_VALID) Valeur attendue : La première lettre est une des 26 lettres ou un tiret bas.

    WARNING: (VARNAME_VALID) Nom de variable incorrect.
    WARNING: (VARNAME_VALID) Valeur actuelle : 1é
    WARNING: (VARNAME_VALID) Valeur attendue : A partir du deuxième caractères, seuls des lettres,
    WARNING: (VARNAME_VALID) des chiffres et un tiret bas sont autorisés.

    Lecture complémentaire

    h1

    Emploi/Formation : Le journal Le Parisien vous offre des exemples de CVs, lettre de motivation

    juin 26, 2010

    Dans ce samedi emploi, je vous propose de découvrir les multiples articles proposé par le journal le parisien sur le CV, la lettre de motivation, l’entretien d’embauche et le stage (rapport, soutenance, etc.) tels qu’ils sont couramment attendus en France.

    1. Pour quel métier êtes vous fait ?

    • Test qui requiert une inscription

    2. Votre CV

    3. La lettre de motivation

    4. Entretien d’embauche

    5. Le stage

    Lectures complémentaires :

    • Une lettre de motivation avec une typographie bien française : Après avoir vu ces dernières années de nombreux CVs et lettres de motivation, il me semble important de rappeler quelques règles de typographie qui s’avèreront essentielle pour avoir une chance de décrocher un emploi. Voici donc un document .pdf de l’IRISA (Institut de Recherche en Informatique et Systèmes Aléatoires) de Rennes en France.
    • 3 raisons pour créer un site Internet pour son CV : Vous recherchez un stage, un emploi utilisant le logiciel sAS et on vous conseille de créer un site Internet pour votre CV. Mais quels sont les avantages de cette approche ?
    • Beaucoup d’entre vous font ou vont faire dans les mois à venir un stage sous SAS. Suite à un article du magazine Management de septembre « Vos obligations vis-à-vis des stagiaires », je vous propose de retrouver tous les détails en termes de législation française sur le site http://www.travail-solidarite.gouv.fr et plus particulièrement vers la page très bien rédigée : Les stages étudiants en entreprise.
    • 8 compétences pour un CV grâce aux loisirs : Faites de vos loisirs un argument pour montrer vos qualités humaines. En plus de vos jobs d’été et vos stages, vos loisirs parlent pour vous. Avant de rechercher une compétence, l’employeur veut un collaborateur qui s’intègre bien à l’équipe en place, qui défend la même philosophie, les mêmes valeurs. C’est une très bonne chose. Cela réduit les chances de passez 5 jours par semaine au boulot avec des personnes qui vont sont antagonistes à défendre des projets que vous désapprouvez. Voici quelques pistes. A vous d’adaptez et de compléter selon votre parcours.
    • 6 conseils pour un CV SAS débutant : Vous commencez vos études et vous voulez mettre toutes vos chances de votre côté pour votre entrée dans la vie activité ? Les études se terminent et vous voudriez devenir consultant SAS ? Comment construire votre expérience et créer un CV débutant béton. Car oui, l’expérience ne fait pas tout. Les recruteurs savent que vous ne connaissez pas le SAS base sur le bout des doigts. Ce qu’il recherche est un peu plus subtil. Voici 8 conseils pour construire un CV attractif.
    • 6 conseils pour un CV bilingue anglais : Aujourd’hui parler l’anglais, ce n’est pas un plus, c’est un pré-requis, comme savoir écrire et savoir allumer un ordinateur. Dans le monde SAS, l’anglais aussi un besoin pour lire et rédiger des supports en anglais, pour dialoguer avec des collègues de différents pays. Comme parvenir à progresser en anglais et à enrichir votre CV ?
    • Ce stage est-il fait pour moi ? 6 questions à se poser. : Dans votre parcours universitaire, vous serez amenés à faire des stages. Ceci est plus qu’une obligation pour obtenir un diplôme. C’est le moyen d’argumenter vos motivations lors de votre future recherche d’emploi. Votre CV en sera grandement enrichi. Voici une série de questions à se poser pour faire un choix stratégique. Ce stage argumenta t-il en ma faveur lorsqu’il s’agira … ?
    • Le SAS vous captive ? 8 astuces pour le montrer dans un CV : Pour construire un CV SAS débutant, il faut savoir montrer son intérêt pour le logiciel … sans avoir à disposition la carte « Expérience ». Il existe quelques astuces pour contourner le problème lorsqu’on a eu que quelques cours obligatoires dans son parcours.
    • Le monde du programmeur SAS en pharma : L’environnement professionnel du programmeur SAS dans le secteur pharmaceutique et plus précisément dans la partie essais cliniques peut ressembler à une boîte noire. Hors SAS est un standard dans ce secteur et les besoins en programmeurs y sont récurrents. Il est donc fort enrichissant d’avoir une connaissance de ce milieu. Pour une immersion dans l’univers des essais cliniques, je vous propose l’article sur le sujet a été écrit par Sy Truong, Meta-Xceed : Clinical Trials Terminology for SAS Programmers. Voici une traduction du résumé et de l’introduction pour vous donner un avant goût de cet article.
    h1

    Comparer deux chaînes de caractères : A quel endroit se situe la première différence ? (la fonction COMPARE)

    juin 20, 2010

    Occasionnellement il peut s’avérer utilise de comparer deux chaînes de caractères et de savoir plus précisément où se situent les différences. La fonction COMPARE peut vous aider dans cette tâche.

    En effet, la fonction COMPARE indique à quel endroit se situe la première différence entre les deux chaînes. Voici un exemple.

    1. Le code

    data one;
    comp1=compare(‘abc’,‘abc’);
    comp2=compare(‘ABc’,‘ABC’);
    comp3=compare(‘A1C’,‘ABC’);
    comp4=compare(‘ABC’,‘A1C’);
    run;

    proc print data=one;
    run;

    2. Interprétation des différents cas

    Dans le premier cas (comparer abc à abc), la fonction retourne une valeur 0 car il n’y a aucune différence. Comme la plupart des fonctions SAS, la valeur zéro indique qu’aucune différence entre les deux chaînes n’a été identifiée.

    Dans le second cas (comparer ABc à ABC), la fonction retourne une valeur 3 car la lettre c située en troisième position est dans un cas écrite en minuscule et dans un cas écrite en majuscule. La fonction est sensible à la case à moins d’ajouter des options dans le troisième paramètre de la fonction.

    Dans le troisième cas (comparer A1C à ABC), la fonction retourne une valeur 2 car la première différence se trouve au niveau du second caractère.

    Dans le quatrième et dernier cas (compare ABC à A1C), le premier et le second texte ont seulement été inversé. La fonction retourne une valeur négative -2 car si on trie les données le chiffre 1 apparaît avant la littre B. Si comme moi, ce qui vous intéresse est uniquement l’endroit où se situe la différence, vous pouvez prendre la valeur absolue en encadrant la réponse dans une fonction ABS().

    Lectures complémentaires :

    h1

    Mettre des données côte-à-côte pour votre reporting

    mai 24, 2010

    Lorsque vous devez présenter vos données (faire du reporting), vous pouvez vous trouver dans la situation suivante : mettre côte-à-côte des données qui n’ont rien à voir entre elles. La situation peut se résoudre très rapidement avec un merge sans instruction BY. Mais que faire dans le cas où vous devez quand même grouper vos données par une clé (exemple l’identifiant du client) mais dans chaque source plus d’une observation par clé ? C’est ce que je vous propose de découvrir dans cet article.

    1. Les données pour l’exemple

    Deborah a deux lignes d’observation et Patrick aussi.

    data demography;
    length cl_name $10 criteria $10 ;
    input cl_name $ criteria $ crit_value ;
    datalines;
    deborah age 15
    deborah height 1.66
    patrick age 14
    patrick height 1.75
    ;
    run;

    Deborah a acheté 4 articles (DVD, téléphone portable, une radio et des écouteurs (4 lignes d’observations pour Deborah) tandis que Patrick a acheté deux articles.

    data sell;
    length cl_name $10 achat $10;
    input cl_name $ achat $;
    datalines;
    deborah dvd
    deborah mobile
    deborah radio
    deborah headset
    patrick mobile
    patrick tv
    ;
    run;

    2. Le résultat sans instruction BY

    data mix_demo_sell;
    merge demography
    sell;
    by cl_name;
    run;

    Vous vous retrouvez avec un merge MANY-to-MANY qui ne résous par votre problème. Pensez toujours à vérifer votre log après un MERGE. Ce type de note est souvent signe d’une erreur de raisonnement dans votre programme.

    proc print data=mix_demo_sell;
    run;

    On observe ici un RETAIN implicite propre au merge.

    3. Ajouter un compteur pour chaque client

    Pour contourner le problème, on ajouter un identifiant supplémentaire dans les deux tables.

    Dans la table DEMOGRAPHY, le client DEBORAH a deux observations. On aura donc CNT=1 et CNT=2.

    data demography;
    set demography;
    by cl_name;
    if first.cl_name then cnt=1;
    else cnt+1;
    run;

    Dans la table SELL, le client DEBORAH a quatre observations. On aura donc CNT=1, CNT=2, CNT=3 et CNT=4.

    data sell;
    set sell;
    by cl_name;
    if first.cl_name then cnt=1;
    else cnt+1;
    run;

    Il ne reste plus qu’à combiner les deux tables à partir de la variable client (CL_NAME) et de la variable CNT.

    data mix_demo_sell;
    merge demography
    sell;
    by cl_name cnt;
    run;

    proc print data=mix_demo_sell;
    run;

    Le résultat désiré se présente ainsi :

    Lecture complémentaire

    h1

    Une petite histoire de macro : compter le nombre de mots dans un paramètre de macro

    avril 11, 2010

    Il est courant de devoir compter le nombre de mots dans un paramètre de macro. Il est par exemple possible de vouloir créer une boucle pour travailler chacun des termes contenu dans cette macro de manière séparée.

    Voici donc l’histoire d’une mini macro qu’on nommera CNT_WRD qui crée une macro variable TOT_WRD renvoyant le nombre de mots contenu dans le paramètre TXT.

    Ceci est pour vous l’occasion de voir ou revoir un raisonnement possible dans la construction d’une macro sous SAS.

    1. Préciser ses besoins, une rapide « spécification »

    La macro CNT_WRD composée d’un seul paramètre retournera dans une macro variable TOT_WRD le nombre de mots contenus dans le texte donné dans le paramètre de macro.

    Ici on considérera comme mot, tout terme séparé par au moins un blanc.

    Si le paramètre de macro est vide, la macro ne devra pas afficher de message d’erreur et la macro variable TOT_WRD sera égale à 1. Par défaut, aucune valeur ne sera entrée dans le paramètre TXT.

    La macro variable doit pouvoir être utilisable à l’extérieur de la macro (macro variable globale).

    2. Tester la fonction COUNT dans une étape data

    La fonction COUNT permet de comptabiliser certains caractères et donc de répondre à ce type de besoin. En fait, cette fonction ne compte pas le nombre de mots mais compte le nombre de caractères définis par le second élément dans la fonction; dans notre cas, elle comptera le nombre de blancs. Il faut donc ajouter 1 au total.

    Voici un exemple dans une étape data.

    data _null_;
    tot_wrd=1+count(‘mot1 mot2’,‘ ‘);
    put tot_wrd=;
    run;

    Dans la log, vous pouvez voir que cnt_wrd=2.

    Mais cela ne suffit pas pour gérer les blancs multiples et les blancs aux extrémités. Car si vous avez plus d’un blanc entre chaque mot, chacun sera compté. Il faut donc les enlever au préalable (avec la fonction COMPBL ici). Les blancs de début et fin peuvent s’enlever au moyen de la fonction STRIP.

    data _null_;
    tot_wrd=1+count(strip(compbl(‘ mot1 mot2 ‘)),‘ ‘);
    put tot_wrd=;
    run;

    Mais que ce passe t-il si notre texte à compter est vide ? TOT_WRD sera égal à 1. Il faut donc ajouter le 1 au total que si le texte à analyser n’est pas vide.

    data _null_;
    length txt $200;
    txt=;
    if txt ne ‘ ‘ then tot_wrd=1+count(strip(compbl(txt)),‘ ‘);
    put tot_wrd=;
    run;

    3. Créer la macro

    Comme indiqué dans le dernier point, on travaille ici de manière conditionnelle. Si le paramètre de macro TXT est vide, la macro variable CNT_WRD nouvellement créée prend la valeur zéro. Sinon, On passe par la fonction COUNT.

    Comme il n’existe pas d’équivalent aux fonctions COUNT et COMPBL en langage macro, il faut encadrer chacune d’elle dans une fonction macro SYSFUNC.

    Ici on notera que la fonction STRIP n’apparaît pas. Les blancs de début et de fin en langage macro n’ont aucun impact.

    %macro cnt_wrd(txt=);

    %global tot_word;

    %if &txt.= %then %let tot_wrd=0;
    %else %let tot_wrd=%eval(1+%sysfunc(count(%sysfunc(compbl(&txt.)),%str( ))));

    %mend cnt_wrd;

    Pour représenter un blanc dans une étape data, il suffit d’utiliser des guillemets. En langage macro, on fait appel à la fonction %STR(). Il faudra ne pas oublier d’ajouter un blanc entre les parenthèses.

    Afin d’ajouter 1 au résultat de la fonction COUNT, il faut utiliser la macro fonction %EVAL. Le contenu des macro variables sont sinon tous interprétés comme du texte, qu’il s’agisse de nombres ou pas.

    Enfin, pour que cette macro variable TOT_WRD soit utilisable en dehors de la macro, il faut qu’elle soit globale. Hors par défaut, une macro variable créée dans une macro est locale, c’est-à-dire n’existe que le temps de la macro. L’instruction %GLOBAL TOT_WRD; résouds le problème.

    4. Tester la macro dans le cadre de sa validation

    Que se passe t-il quand on ne change pas la valeur par défaut du paramètre de macro ?

    %cnt_wrd;
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il quand le paramètre de macro TXT est vide de texte ?
    %put Valeur de TOT_WRD: &tot_wrd;

    %cnt_wrd(txt=);
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il lorsqu’il n’y a qu’un mot?

    %cnt_wrd(txt=mot1);
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il quand il y a plusieurs mots ?

    %cnt_wrd(txt=mot1 mot2 mot3);
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il quand il y a des blancs multiples entre les mots, en début et à la fin ?

    %cnt_wrd(txt= mot1 mot2 mot3 );
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il quand il y a des blancs multiples entre les mots, en début et à la fin ?

    %cnt_wrd(txt=mot1 mot2);
    %put Valeur de TOT_WRD: &tot_wrd;

    Que se passe t-il quand la macro est appelée plusieurs fois ?

    %cnt_wrd(txt=mot1 mot2);
    %put Valeur de TOT_WRD: &tot_wrd;
    %cnt_wrd(txt=mot1);
    %put Valeur de TOT_WRD: &tot_wrd;

    Lecture complémentaire

    h1

    Qui a la priorité : RETAIN ou SET ?

    mars 30, 2010

    L’instruction RETAIN permet d’assigner une valeur à une variable.  La valeur est reconduite à l’observation suivante à moins d’être changée par une autre instruction au cours de l’étape data.

    Le point à retenir dans cet article est que si la variable existe déjà, RETAIN ne va pas pouvoir réécrire la valeur.

    Afin de représenter cette logique dans son programme, il peut-être conseillé d’écrire l’instruction RETAIN avant une instruction qui lie de nouvelles donnée ; SET par exemple.

    1. Voir la logique

    La variable qui existe dans le fichier d’origine : Dans cet exemple, on voit que la variable AGE qui existe dans le fichier d’origine SASHELP.CLASS n’est pas changée par l’instruction RETAIN.

    La variable qui n’existe pas avant : Par contre la variable AGE2 qui n’existe pas dans le fichier d’origine prend bien la valeur donnée dans l’instruction RETAIN.

    data class;
    set sashelp.class;
    retain age 0 age2 0;
    run;

    proc print data=class noobs;
    run;

    2. Etre logique

    Afin de respecter cette logique, l’instruction RETAIN est à placer avant l’instruction SET.

    data class;
    retain age 0 age2 0;
    set sashelp.class;
    run;

    proc print data=class noobs;
    run;

    Lectures complémentaires

    SAS Online Doc

    • RETAIN Statement
    h1

    Une fonction LIBREF au résultat inattendu

    mars 23, 2010

    La fonction LIBREF vérifie l’existence d’une bibliothèque. Vu que la réponse attentue est oui ou non, on pourrait s’attendre à une résultat binaire avec zéro pour non et un pour oui. Dans les faits, cette fonction retourne zéro pour oui et toute autre valeur signifie non.

    Voici un exemple.

    1.  Contexte, exemple

    Vous cherchez à savoir si le chemin d’accès défini dans un  paramètre de macro peut servir de bibliothèque. Une solution est de tenter de créer la bibliothèque et ensuite de vérifier si la bibliothèque a été créée ou non.

    2. Le programme

    Dans l’exemple qui suit, une macro TEST est créée. Elle a un paramètre DSNPATH=. Le chemin d’accès donné dans ce paramètre est utilisé pour créé la bibliothèque INLIB.

    Ensuite pour les besoins de l’exemple, un message est ajouté dans la log au moyen des instructions %PUT.

    • Tout d’abord, est indiqué dans la log la valeur prise par le paramètre de macro DSNPATH.
    • Puis, la valeur prise par la fonction LIBREF est affiché dans la log.

    Afin de pouvoir utiliser cette fonction hors d’une étape data ou d’une procédure PROC SQL, il faut l’englober dans une macro fonction %SYSFUNC().

    En fin de macro la référence à la bibliothèque est supprimée.

    %macro test(dsnpath=);
    libname inlib « &dsnpath. »;
    %put MESSAGE: DSNPATH= &dsnpath.;
    %put MESSAGE: Voir le résultat de la fonction LIBREF dans la log: %sysfunc(libref(inlib));
    libname inlib;
    %mend test;

    Le premier appel de macro se fait avec un chemin d’accès valid. Tandis que le second appel de macro utilise un chemin d’accès erroné.

    %test (dsnpath=C:/sasref);
    %test (dsnpath=C:/sasre);

    3. La log

    Lorsque le chemin d’accès est correct, la fonction LIBREF retourne la valeur 0.

    Quand le chemin d’accès n’est pas correct, la fonction LIBREF retourne une valeur différente de zéro. Dans l’exemple, il s’agit de la valeur -70008.

    Lectures complémentaires

    Autres articles sur %SYSFUNC

    SAS Online Doc

    • Summary Descriptions and Syntax
    • LIBREF Function
    h1

    Protégé : Newsletter Mars : solution

    mars 1, 2010

    Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

    h1

    Protégé : Newsletter Mars : Exercice

    mars 1, 2010

    Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

    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

    Quand l’option NOLABEL réserve des surprises !

    février 22, 2010

    L’option global NOLABEL permet notamment de ne pas afficher les labels dans un PROC SQL. Comme tout option globale, il est courant d’ajouter ce type d’instruction en début de programme. Est-ce que cette option a des conséquences sur l’allocation des libellés sur les variables ou ailleurs ?

    1. Assigner un label aux variables du data set CLASS

    Dans l’exemple qui suit un data set CLASS est créé. Un libellé est ajouté aux variables NAME et HEIGHT. Au préalable l’option global NOLABEL est ajoutée.

    options nolabel;

    data class;
    label name = ‘Nom’ height=‘Taille’;
    set sashelp.class;
    run;

    2. Que constate t-on lorsque l’option NOLABEL est active ?

    En consultant la description des données avec un PROC CONTENTS ou un PROC SQL, les labels n’apparaissent pas.

    proc contents data=class varnum;
    run;


    proc sql;
    select name, label
    from dictionary.columns
    where upcase(libname)=‘WORK’ and
    upcase(memname)=‘CLASS’;
    quit;


    3. Que se passe t-il une fois que l’option LABEL est de nouveau active ?

    Une fois l’option LABEL actif, les libellés sont bien assignés aux variables. Ils ne sont simplement invisibles tant que l’option NOLABEL est active.

    options label;

    proc contents data=class varnum;
    run;

    proc sql;
    select name, label
    from dictionary.columns
    where upcase(libname)=‘WORK’ and
    upcase(memname)=‘CLASS’;
    quit;