Archive for the ‘count’ Category

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

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

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

Identifier et supprimer les doublons

juillet 14, 2008

Identifier et supprimer les doublons dans un data set fait partie des compétences de base du programmeur SAS. Trois approches sont envisageables : PROC SQL, PROC SORT et un compteur dans un data step.

Qu’appelle-t-on doublon ? des lignes complètement identiques ou seulement des lignes ayant quelques variables communes ? Il est important de savoir si deux records ayant des observations communes sont considérés comme doublons ou s’il faut que toutes les observations soient identiques. Si seules quelques variables sont considérées, il faut savoir quelle ligne est conservée et lesquelles sont supprimées.

Le data set utilisé pour l’exemple est composé de trois variables CNTRY (country), PAT_ID (patient ID) et VAL (value). Le patient 2 de Chine a trois lignes d’observations dont deux strictement identiques.

cntry    pat_id    val

 CN        1        A
 CN        2        B
 CN        2        C
 CN        2        C
 HK        3        E 

1. PROC SQL

Avec la procédure SQL, il est possible de faire des calculs et de baser sa sélection d’observations sur ce calcul. En d’autres termes, il est possible de compter le nombre de fois qu’une valeur apparaît. Pour identifier les records avec doublons, on prend ceux comptés plus d’une fois.

Première présentation : Voici, tout d’abord, une présentation de PROC SQL décomposable en deux étapes.

proc sql;
   create table two (where=(cnt_pat > 1)) as
      select cntry, pat_id, val, count(*) as cnt_pat
      from one
      group by cntry, pat_id;
quit;

Dans un premier temps, une variable donne le nombre de records par patient dans un pays donné (CNT_PAT) grâce à la syntaxe GROUP BY et la fonction COUNT. A ce stade, on obtient le data set suivant :

cntry pat_id val cnt_pat

  CN     1    A     1
  CN     2    C     3
  CN     2    B     3
  CN     2    C     3
  HK     3    E     1

Dans un second temps, seules les observations ayant des doublons sont gardées, une fois le nouveau data set créé, grâce à l’option WHERE=.

Deuxième présentation : Au lieu de créer la variable CNT_PAT et de faire une sélection ultérieure, la fonction COUNT peut être  ajoutée dans une condition introduite par le mot HAVING et faisant toujours appel à la fonction COUNT.

Pour ne voir qu’une des lignes multiples, il suffit d’ajouter DISTINCT.

proc sql;
   create table two_bis as
   select /*distinct*/ cntry, pat_id, val
   from one
   group by cntry, pat_id
   having count(*) > 1;
quit;

A l’inverse, pour ne sélectionner que les observations n’apparaissant qu’une fois, « >1 » sera remplacé par « =1 ». Seules les observations ayant exactement une occurrence sont sélectionnées.

Le DISTINCT s’applique à l’intégralité des observations. Cela permet de ne garder que des lignes uniques.

Il n’est pas possible de garder la première ligne parmi les doublons définis par des variables précises (CNTRY et PAT_ID dans l’exemple) avec cette méthode.

2. Les options de la procédure PROC SORT (NODUP/NODUPRECS, NODUPKEY)

Il existe deux options dans la procédure PROC SORT pour supprimer les doublons selon qu’ils s’appliquent

  • à toute une ligne d’observation (NODUPRECS dont l’alias est NODUP) ou
  • à une liste de variables précises données dans l’instruction BY (NODUPKEY).

Au choix, le nouveau data set sans doublons remplace l’ancien ou est sauvegardé dans un dataset différent introduit par OUT=.

Les observations ayant été exclues peuvent être sauvegardées dans un nouveau data set dont le nom est défini par DUPOUT=.

proc sort data=one out=three nodupkey dupout=three_bis;
   by cntry pat_id;
run;

proc sort data=one out=four noduprecs /*nodup*/ dupout=four_bis;
   by cntry pat_id;
run;

3. Appliquer une variable compteur

Enfin, après PROC SQL et PROC SORT, une troisième possibilité pour identifier et supprimer les doublons, est d’ajouter une variable compteur.

Dans l’exemple ci-dessous, la variable compteur est nommée CNT. Pour la première observation d’un patient d’un pays donné, le compteur est initialisé à 1. Pour chaque nouveau record du patient, le compteur est incrémenté de 1. Quand la variable CNT est égale à 1, le record est ajouté dans le data set FIVE. Sinon il est ajouté dans le data set FIVE_BIS. A la fin, la variable compteur est supprimée.

Ainsi le data set FIVE contient les records sans doublons. Dans le cas du patient doublonné (patient 2), c’est la première observation qui est conservée.

Dans le data set FIVE_BIS, les records exclus de la première sélection sont conservés.

data five (drop=cnt) five_bis (drop=cnt);
   set one;
   by cntry pat_id val;
   if first.pat_id then cnt=1;
   else cnt+1;
   if cnt = 1 then output five;
   else output five_bis;
run;

Annexe :

data one;
   input cntry $ pat_id $ val $;
   datalines;
CN 1 A
CN 2 B
CN 2 C
CN 2 C
HK 3 E
;
run;

h1

Mes valeurs sont t’elles proches de la moyenne ? (écart-type)

juin 17, 2008

Pour résumer une série de mesures, il est courant de proposer la moyenne. Mais avoir une moyenne de 11 n’a pas le même sens selon que les valeurs soient dispersées entre 10 et 13, ou entre 0 et 20. Dans le premier cas, toutes les valeurs sont plus proches de la moyenne que dans le second cas. L’écart-type (ou standard deviation en anglais) reflète cette subtilité. Le statisticien aura pour rôle d’interpréter cette valeur. En comprenant le sens d’un écart-type,  le programmeur trouvera un outil supplémentaire pour vérifier la cohérence de ses résultats.

1. Des variables continues

La moyenne et l’écart-type sont des outils s’appliquant uniquement aux données numériques, suivant un ordre donné où l’écart entre chacune des valeurs potentielles est toujours le même. On peut donc parler de valeurs continues au sens large du terme.

Ainsi, l’âge d’une personne est une donnée continue qu’elle soit arrondie en années, en mois, en jours, en heure. La moyenne et l’écart-type auront une précision similaire.

2. Définition l’écart-type d’une population

L’écart-type ayant pour but de chiffrer l’écart entre les valeurs  et la moyenne. Il est donc logique de calculer la différence entre chaque valeur et la moyenne. Dans un premier temps, on a autant de différences que de valeurs. Dans un second temps, une valeur moyenne est extraite de ces différences.

1. Mettre au carré les différences : qui dit moyenne, dit somme des valeurs divisé par le nombre de valeur. Hors, la somme de valeurs positives et négatives s’annulent. Et dans notre cas, on a bien des valeurs inférieures et des valeurs supérieures à la moyenne. Dans le cas de l’écart-type, toutes les différences sont rendues positives en les multipliant par elles-mêmes (mises au carré).

C’est probablement pour des faciliter la résolution de calculs mathématiques que la mise au carré est préféré à la prise des valeurs absolu. Si vous avez une autre hypothèse, n’hésitez pas à en faire part.

2. Extraire la moyenne : on souhaite une moyenne. Donc la somme des différences (mises au carré) sont divisées par le nombre de différences. Si on s’arrête là, la statistique s’appelle la variance.

3. Exprimer la dispersion dans la même unité que la moyenne : A présent la somme des différences n’est plus dans la même unité que la moyenne. Pour parler dans la même unité, on prend la racine de l’ensemble du calcul.

3. Estimer l’écart-type d’une population à partir d’un échantillon

Contexte : il est fréquent de ne pas travailler sur la population qui nous intéresse mais sur un échantillon. Par exemple, si on mesure la pression artérielle systolique des patients d’une étude clinique pour savoir si la drogue a permis de la réduire, le statisticien n’est pas intéressé par la moyenne de ces patients mais bien celle de tous les personnes pouvant à l’avenir faire appel à cette drogue.

Le problème : De plus, les recherches statistiques ont permis de démontrer qu’en moyenne, la moyenne de tous les échantillons possibles est la même que celle de la population. Pour l’écart-type, c’est un peu moins simple, puisqu’il la moyenne des écarts-types de tous les échantillons n’est pas exactement égale à celle de la population.

La solution : Mais les chercheurs en statistique sont là ! Ils ont réussi à montrer qu’en enlevant 1 au nombre total de valeurs dans chacun des échantillons, on pouvait retrouver l’écart-type de la population (cf. des cours d’inférence qui semble si théorique au prime abord mais qui permettent d’accéder à l’arrière de la scène).

Vocabulaire : Et pour enrichir votre vocabulaire et surtout comprendre ces spécialistes sachez que si l’écart-type sera appelé un estimateur biaisé si le 1 n’est pas enlevé.

L’écart-type le plus utilisé est donc le second, celui où on divise les différences non pas par le nombre de différences mais le nombre de différences moins 1.

4. Comprendre la différence entre l’écart-type et l’erreur-type

Pour ceux qui auront une formation à composante statistique, vous pourrez être amené à expliquer en entretien ou à vos collègues la différence entre l’écart-type (standard deviation) et l’erreur-type (standard error). 

La première différence, c’est que l’écart-type s’applique à des données, alors que l’erreur-type s’applique à la statistique de la moyenne. 

A chaque fois, qu’un échantillon est pris, sa moyenne va servir à estimer la moyenne de la population. Bien-sûr, toutes les moyennes des échantillons ne sont pas identiques. Il existe une variabilité. Certains sont plus proches de la réalité que d’autre. Cette variabilité des résultats entre les échantillons est donnée par l’erreur-type. Ainsi un intervalle à l’intérieur duquel la moyenne de la population se tient pourra être estimé.

5. En langage mathématique, l’écart-type donne quoi ?

Pour désigner nos valeurs, le mathématicien utilise la lettre X.

  • Xi représente la ième valeur de l’échantillon. Si on a 15 valeurs alors i prend les valeurs de 1 à 15 ou plus généralement les valeurs de 1 à n.
  • La moyenne de ces Xi est symbolisée par un X avec une barre au dessus.

Pour calculer l’écart-type, on a parlé de trois étapes :

  1. sum(Xi-Xbar)2 Tout d’abord la différence entre chaque Xi et la moyenne X barre est calculée. Elles sont mises au carré. Puis, la somme de ces valeurs en est faite. On en profite pour préciser que les valeurs de i vont de 1 à n.
  2. sum(Xi-Xbar)2 / (n-1) Après, il s’agit de calculer la moyenne de ces valeurs
  3. racine(sum(Xi-Xbar)2 / (n-1)) Enfin, la statistique est convertie en une unité comparable à celle de la moyenne via la racine carré.

6. Et en langage SAS, comment trouver la valeur d’un écart-type ?

Dans tous les cas suivant, le dénominateur est n-1.

6.1 Fonction STD : La fonction STD (standard deviation) retourne la valeur de l’écart-type.

proc sql;
   select std(age) as std_age
   from sashelp.class;
quit;

6.2 Calcul manuel : dans un premier temps, la différence avec l’âge moyen est calculée pour chaque record. Chaque différence est mise au carré. Dans un deuxième temps, la somme de ces différences est divisée par le nombre de records moins 1. Enfin, la racine carrée du tout est prise.

proc sql;
   create table step1 as
      select (age-mean(age))**2 as step1
      from sashelp.class;
   select sqrt(sum(step1)/(count(*)-1)) as step2_3
      from step1;
quit;

6.3 Les procédures PROC MEANS et PROC SUMMARY : dans les exemples ci-dessous, j’ai volontairement choisi l’instruction ODS OUTPUT pour extraire les statistiques dans un data set.

proc means data=sashelp.class;
var age;
ods output Summary=proc_means;
run;

proc summary data=sashelp.class print;
   var age;
   ods output Summary=proc_summary;
run;

6.4 La procédure PROC UNIVARIATE : deux sorties fournies par la procédure UNIVARIATE sont indifféremment disponible.

proc univariate data=sashelp.class;
   var age;
   ods output Moments=proc_univ_opt1;
   ods output BasicMeasures=proc_univ_opt2;
run;

h1

Combien d’observations dans mon data set ?

avril 14, 2008

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

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

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

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

data orig;
x=1;

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

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

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

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

%put METHOD 1 = &methode1. ;


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

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

%put METHODE 2 = &sqlobs. ;

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

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

%put METHODE 3 = &methode3. ;

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

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

%put METHODE 4 = &methode4. ;

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

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

%put METHODE 5 = &methode5. ;

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

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

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

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

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

 

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

h1

Fini le Moyen-Age pour compter les mots

février 20, 2008

ulrepforte.jpg 

Vous avez une variable composée d’un ou plusieurs mots pour chaque observation, le tout séparé par des espaces, des virgules ou autre. Et vous voulez savoir combien il y a de mots. Avec SAS 9, il est très rapide de trouver le nombre de mots. Avec SAS 8.2, il faut pallier à l’absence de la fonction COUNT. Dans les deux cas, l’idée est la même : on compte les délimiteurs et on ajoute 1.

Prenons le cas des espaces. Dans un premier temps, on enlève les blancs de début et de fin de chaîne. Puis on enlève les doublons entre les mots. Enfin on compte les espaces restants. Il faudra aussi tenir compte du fait qu’une observation puisse ne contenir aucune valeur.

Voici les données qui serviront d’exemple :

data ds_orig;
   x=‘ AB CD GH ‘;
   output;
   x=‘ ‘;
   output;
   x=‘AB ‘;
   output;
run;

1. Avec SAS 9, un calcul rapide : il faudra faire appel à:

  • la fonction STRIP pour les blancs aux extrémités,
  • la fonction COMPBL pour enlever les blancs doublons,
  • la fonction COUNT  pour compter le nombre d’occurrence d’un caractère donné,
  • la fonction MISSING ou un simple = ‘ ‘ pour savoir si la chaîne est vide.

Voici un exemple avec des espaces pour délimiteur.

data sas9 ;
   set ds_orig;
   if x = ‘ ‘ then nb_mots = 0;
   else nb_mots=count(compbl(strip(x)),‘ ‘) + 1;
run;

2. Avec SAS 8.2, il faut contourner l’absence de la fonction COUNT: il existe plusieurs options dont celle-ci utilisant une boucle DO WHILE

  • Les fonctions TRIM et LEFT remplacent la fonction STRIP.
  • Les fonctions COMPLB et MISSING restent valide.
  • Une boucle remplacera la fonction COUNT.

On extrait le 1er mot de la chaîne, puis le 2nd, etc. via la fonction SCAN. Si la valeur trouvée est une valeur manquante, alors le nombre de mots est égal au nombre du boucles sans valeur manquante, c’est-à-dire le nombre de boucles actuel moins 1. Le compteur, ici nommé i, est réinitialisé pour arrêter la boucle DO WHILE.


data sas8_2;
   set ds_orig;
   if missing(x)then cnt_mots=0;
   else
      do;
         z=compbl(trim(left(x)));
         i=1;
         do until (i=0);
         if missing(scan(z,i,‘ ‘))then
            do;
               cnt_mots=i-1;i=->1;
               end;
               i=i+1;
            end;
         drop i z;
   end;
run;

h1

3 méthodes pour construire des macros variables sans macro

février 7, 2008

Les macro-variables peuvent être créées soit à l’intérieur d’une macro, soit à l’extérieur. Ici je vous propose de voir comment les créer indépendamment d’une macro. Pour une valeur brute indépendante du reste de votre programme, je vous propose le statement %let. Pour des macros variables définies à partir d’autres informations disponibles dans un jeu de données, vous aurez le choix entre le statement ‘CALL SYMPUT’ dans un data step et le mot clé ‘INTO :’ dans une procédure SQL.

1. Assigner une valeur manuellement : L’instruction %LET sert à définir une macro variable quand vous connaissez la valeur à donner à votre macro variable à l’avance et qu’elle n’est pas fonction de vos données. Tapez la valeur de votre macro-variable. Pour chaque %LET statement une macro variable est créée. Faites suivre %LET du nom de la variable et saisissez sa valeur après le signe égal.

%let projet=53269 ;

2. Créer une macro variable dans un data step : pourquoi vouloir passez par un data step ? Voici deux exemples : assigner la valeur d’une variable automatique comme _N_ ; créer une boucle pour créer autant de macros variables qu’il y a de valeurs distinctes dans une variable.

2.1 La distinction entre CALL SYMPUT et CALL SYMPUTX : les arguments de CALL SYMPUT sont le nom de la macro variable dans un premier temps, et sa valeur dans un second temps. Jusqu’à SAS 8.2, on devait convertir les valeurs numériques en valeur caractères, via la fonction PUT, pour créer la macro variable. Depuis SAS 9, on peut directement utiliser la valeur numérique avec CALL SYMPUTX.

data _null_ ;
   set demo;
   call symputx(‘Nb_boucle’,_N_);
run;

Pourquoi cette nouveauté si tardive ? Parce que la valeur d’une macro variable est toujours caractère. Dans un macro statement tel %if…, vous aurez besoin d’une macro fonction pour faire la somme de deux macro variables. En dehors, vous devrez écrire la macro variable entre double guillemets.

2.2 Un seul CALL SYMPUT(X) et plusieurs macros variables : si vous avez un jeu de données avec deux variables : une contenant le nom de vos futures macro-variables et l’autre leur valeur, vous pouvez avec un seul CALL SYMPUT/SYMPUTX créer toutes les macro-variables. Pour cela, il vous suffit de mettre le nom des deux variables dans les paramètres. Cette fois-ci il n’y a plus de guillemets.

Niveau Dose
Dose1 50
Dose2 100
Dose3 150
call symputx (niveau,dose);

3. Créer une macro variable dans une procédure SQL : Vous pouvez répondre à trois besoins avec PROC SQL : 1) sauvegarder une valeur unique dans une macro variable, comme le nombre total d’observations dans un jeu de données ; 2) sauvegarder toutes les valeurs prises par une variable dans une seule macro variable, en jouant avec SEPARATED BY. 3) créer autant de macro variable qu’il y a de valeurs sélectionnées.

3.1 Une macro variable ayant une seule valeur : pour sauvegarder le nombre d’observations d’un data set dans une variable CNT, vous écririez select count(*) as cnt from demo ; Pour sauvegarder cette information dans une macro variable CNT vous remplacerez ‘AS’ par ‘INTO :’

proc sql;
   select count(*) into : cnt
      from sashelp.class ;
quit;

3.3 Plusieurs macros variables à partir de plusieurs valeurs: la syntaxe suivante permet de créer plusieurs macros variables à partir de plusieurs calculs extraits d’un même data set.

proc sql;
   select distinct count(age), count(*)
              into : cnt_age,
                   : cnt_rec
       from sashelp.class;  
quit;

Si les noms de variables ont un nom schématique (base + nombre incrémenté par 1), la syntaxe suivante peut être appliquée.

proc sql;
   select distinct age into : pop1-:pop6
      from sashelp.class;
quit;

3.4 Plusieurs valeurs dans une seule macro variable: vous pouvez aussi décider de sauvegarder ces cinq valeurs dans une seule macro variable. Ne listez alors qu’un nom. Au moment d’appeler votre macro vous observerez que seule la première valeur apparaît si vous n’avez pas précisez un délimiteur comme un espace ou une virgule entre les observations via SEPARATED BY. Par défaut, le délimiteur est en effet un passage à la ligne. Voici deux exemples :

proc sql;
   select distinct age into : age_space
                            separated by ‘ ‘
      from sashelp.class;
   select distinct age into : age_comma
                           separated by ‘,’
      from sashelp.class;
quit;

 
3.5 La macro variable automatique SQLOBS : Enfin sachez qu’il existe une macro variable automatique SQLOBS qui sauvegarde le nombre d’observation de la dernière procédure SQL. Cette fonction peut s’avérer pratique à condition de bien garder à l’esprit qu’il ne faudra pas par la suite intercaler d’autres SQL statement qui changeraient la valeur de cette macro variable automatique.

3.6 Extra

L’option NOPRINT : Par défaut, les valeurs d’un select statement sont affichées dans la log, si aucun jeu de données n’est crée. Si vous ne souhaitez pas voir la valeur des macros variables s’afficher dans votre log arrêter via l’option NOPRINT :

   proc sql noprint;
      *ma sélection;
   quit;

Important: si aucun record n’est sélectionné avec la PROC SQL, la macro variable n’est pas créée. Dans l’exemple ci-dessous, la macro variable MAX_AGE n’apparaît pas dans la liste des variables de l’utilisateur disponible dans la log.

proc sql noprint;
   select max(age) into : max_age
   from sashelp.class
   where age > 18;
quit;

%put _user_;

4. Supprimer une macro variable globale

Les macros variables globales sont disponibles tout le long de la session. On peut choisir d’écraser la valeur en créant une nouvelle macro variable portant le même nom ou choisir de la supprimer. Dans la version 9.1.3, l’instruction globale %SYMDEL fait supprime les macros variables globales pour vous. Pour ce qui est des variables locales, il n’y a pas d’instructions pour la simple raison que la valeur de la macro variable ne peut pas être rappelée en dehors de la macro.

%symdel cnt cnt_age cnt_rec pop1 pop2 pop3 pop4 pop5 pop6 age_space age_comma;

NOTE : Pour définir une condition basée sur une macro variable, il faut qu’elle existe. Si une macro variable n’est pas créée, faute de valeur à assigner, il est conseillé de définir au préalable une valeur par défaut avec un %LET par exemple. Elle pourra ensuite être actualisée par une des trois méthodes mentionnées ci-dessus. Une autre solution est de s’assurer de l’existence de la macro variable avec la fonction %SYMEXIST.