Posts Tagged ‘mot’

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

Mon petit doigt me dit que… le mot commence en position 2 (Fonction INDEX)

octobre 10, 2008

Pour savoir si un mot est présent dans une chaîne de caractère, il y a la fonction INDEX. Celle-ci retourne la position d’un « mot » dans une chaîne de caractère. Parmi les fonctions qui lisent les observations textuelles sous SAS, la fonction INDEX fait probablement partie du top 10 des fonctions les plus usuelles.

1. Deux paramètres de base

La chaîne de caractères à analyser est le premier paramètre de la fonction INDEX. Comme toute fonction, elle définie au choix par :

  • le texte entre guillemets
  • la variable caractère contenant toutes les observations à traiter.

Le texte à trouver est le second paramètre de la fonction INDEX. On le donne généralement entre  guillemets.

2. Que retourne la fonction ?

La fonction retourne un nombre : le nombre généré par la fonction INDEX représente la position de la première lettre du mot recherché. Si plusieurs mots sont disponibles dans la chaînes, SAS s’arrête au premier.

Et si aucun mot n’est présent ? Dans le cas où le mot n’est trouvé, la fonction INDEX retourne la valeur zéro. Ainsi si INDEX retourne une valeur supérieure à zéro, le mot est présent dans la chaîne de caractère, sinon il est absent.

3. Minuscules ou majuscules

La lettre A (majuscule) et a (minuscule) ne sont pas identiques. La fonction est sensible à la case.

Si la case de la chaîne de caractère vous importe peu, considérez la chaîne de caractères mise en majuscule (par exemple) avec la fonction UPCASE.

4. Un exemple

Dans l’exemple ci-dessous, le data set ONE a une ligne d’observation et trois variables X, Y et Z.

La variable Y retourne la position du mot ‘de’ (minuscule) dans la chaîne de caractères ‘ABC def DEG’. Il s’agit donc de la position 5.

La variable Z retourne la position du mot ‘DE’ (majuscule) dans la chaîne de caractères ‘ABC def DEG’. Il s’agit donc de la position 9.

data one;
x=‘ABC def DEG’;
y=index(x,’de’);
z=index(x,’DE’);
run;

h1

Scanner une chaîne de caractère et extraire le xème mot

septembre 12, 2008

Scanner le contenu d’un texte et identifier le xème « Mot » est possible sous SAS grâce à la fonction SCAN. Je vous propose dans un premier temps de voir les différents paramètres de la fonction. Puis dans un second temps, vous aurez à disposition quelques exemples documentés à tester soi-même.

Deux exemples d’applications :

  • Définir une condition (IF THEN par exemple) selon la valeur prise par le mot trouvé.
  • Sauvegarder le « mot » dans une nouvelle variable.

1. Trois paramètres pour la fonction SCAN

La fonction SCAN est composée de trois paramètres.

  1. Le texte à scanner
  2. La position du mot recherché
  3. Le symbole délimitant les mots dans le texte

1.1 Le texte à scanner est donné dans le premier paramètre

Le texte à scanner peut-être une chaîne tapée manuellement entre guillemets. Mais il est plus probable que vous souhaitiez opérer l’opération pour chacune des observations contenues dans une variable caractère.
Il s’agit alors de nommer la variable.

Rappel : lorsqu’une variable est nommée, il ne faut jamais mettre son nom entre guillemets. La fonction SCAN ne fait pas exception.

1.2 La position du mot recherché est définie dans le second paramètre

Des nombres entiers : la position du mot est donnée par un nombre entier.

  • 1 correspond au premier mot de la chaîne de caractères;
  • 2 au deuxième, etc.

Les valeurs négatives : il est en effet possible d’utiliser des valeurs négatives pour définir la position du mot. De quoi s’agit-il ? Tout simplement, au lieu de commencer par le début de la chaîne, SAS commence par la fin.

  • -1 correspond au dernier mot,
  • -2 à l’avant dernier mot, etc.

1.3 Le délimiteur apparaît en troisième

Trouver des « mots » au sens large du terme : En langage courant, un mot est un ensemble de lettres séparées par un espace. Avec la fonction SCAN, le symbole séparant les mots est libre. L’utilisateur se chargera de définir ce symbole.

Le symbole séparant les mots est à donner entre guillemets. A titre d’exemple, il peut s’agir de tirets bas (underscore en anglais), de barre inclinée (slash en anglais), de blancs (blank en anglais).

2. La fonction SCAN par l’exemple

Exemple 1 : Dans ce premier exemple, une variable NAME contient 5 observations.

data dict;
   length name $8;
   input name $;
   datalines;
PAT_ID
COUNTRY
REC_ID
VISIT
VISIT_DT
;
run;

Grâce à la première condition, les observations se terminant par _DT sont sauvegardées dans le data set DT_VAR. Il n’y a que la variable VISIT_DT.
Avec la seconde condition, les observations commençant par VISIT_ sont envoyées dans le data set VISIT_VAR.

data dt_var visit_var;
   set dict;
   if scan(name,-1,‘_’)=‘DT’ then output dt_var;
   if scan(name,1,‘_’)=‘VISIT’ then output visit_var;
run;

Exemple 2 : Dans ce second exemple, une variable PATH a 3 observations.

data path_lst;
   path=‘c:/sasref/projet123/study1/pgm’;
   output;
   path=‘c:/sasref/projet123/study9/pgm’;
   output;
   path=‘c:/sasref/projet444/study2/pgm’;
   output;
run;

Dans ce premier cas, les observations contenant le mot proj123 en troisième niveau dans le chemin d’accès sont gardées.

data projet123;
   set path_lst;
   if scan(path,3,‘/’)=‘projet123’;*then output;
run;

Dans ce second cas, une nouvelle variable est créée. Elle contient le numéro de l’étude disponible en quatrième position dans le chemin d’accès fourni dans la variable PATH.

data study_var;
   study=scan(path,4,‘/’);
run;

Je vous donne rendez-vous demain samedi pour un article sur l’option FMTSEARCH.