Archive for the ‘scan’ Category

Scanner une chaîne de caractère et extraire le xème mot
septembre 12, 2008Scanner 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.
- Le texte à scanner
- La position du mot recherché
- 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.

Diriger les sorties d’un PROC MEANS dans un dataset SAS
juillet 24, 2008Par défaut, les résultats des procédures SAS sont affichés dans la fenêtre OUTPUT. Pour convertir ces résultats en tableau SAS (SAS dataset), la syntaxe de l’ODS (Output Delivery System) dispose d’outils appropriés comme les instructions
- ODS TRACE pour identifier une sortie,
- ODS OUTPUT pour rediriger une sortie vers un data set,
- ODS SELECT and ODS EXCLUDE pour choisir les sorties apparaissant dans la fenêtre OUTPUT.
Pour illustrer ce sujet, la procédure PROC MEANS sera utilisée.
Remise dans le contexte :
- Changer l’éditeur pour une présentation plus fine : rediriger vers un document RTF avec ODS RTF s’applique une fois que la formulation nous convient.
- Changer la formulation des informations : le TEMPLATE peut préalablement être modifié pour n’afficher qu’un sous ensemble du résultat par exemple.
- Faire de gros travaux : pivoter un tableau, combiner des résultats entre eux ou encore calculer une valeur à partir des résultats existant fait partie des gros travaux qui nécessitent de passer par un dataset SAS.
1. Identifier le nom des résultats
Pour voir le nom des différentes outputs, entourez votre procédure des instructions ODS TRACE ON/LISTING et ODS TRACE OFF.
- La première instruction demande l’affichage de chacune des noms des sorties.
- L’option LISTING permet d’afficher cette information dans la fenêtre OUTPUT. La destination par défaut est la LOG.
- Enfin, la seconde instruction désactive le traçage.
Premier exemple
ods trace on/listing;
*Exemple 1 : Proc Means;
proc means data=sashelp.class;
var height weight;
run;
ods trace off;
On obtient la sortie de PROC MEANS appelée SUMMARY.
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.Summary
————-
Second exemple avec une instruction BY : il est toujours possible d’ajouter une instruction BY dans PROC MEANS.
proc sort data=sashelp.class out=class;
by sex;
run;
ods trace on/listing;
*Exemple 2 : Proc MEANS et l’instruction BY;
proc means data=class;
by sex;
var height weight;
run;
ods trace off;
Il y a plusieurs outputs pour une seule procédure. Les deux sorties ont le même nom (NAME) mais le chemin d’accès (PATH) est différent. On parle de BYGROUP1 et BYGROUP2 pour les distinguer.
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.ByGroup1.Summary
————-
Output Added:
————-
Name: Summary
Label: Summary statistics
Template: base.summary
Path: Means.ByGroup2.Summary
————-
2. ODS OUTPUT et PROC MEANS
Dans le premier exemple, un data set EXEMPLE1 est créé à partir de la sortie ONEWAYFREQ de la PROC MEANS appliquée au fichier SASHELP.CLASS.
J’ai choisi d’écrire l’instruction ODS OUTPUT à l’intérieur de la procédure puisqu’elle s’applique uniquement à la procédure mais elle peut être aussi affichée avant la procédure.
Une seule instruction pour plusieurs data sets à créer : Ecrire l’instruction ODS OUTPUT avant la procédure est intéressant si vous générez plusieurs sorties de procédures différentes et voulez lister tous les data sets SAS à créer en une seul instruction ODS OUTPUT.
*Exemple 1 : Proc Means;
proc means data=sashelp.class;
var height weight;
ods output summary=exemple1;
run;
Un fichier brut peu lisible : Après un PROC PRINT sur le data set EXEMPLE1, on découvre un fichier peu lisible dès qu’il y a plus d’une variable.
VName_
Height Height_N Height_Mean
Height 19 62.336842105
Height_
StdDev Height_Min Height_Max
5.1270752466 51.3 72
VName_
Weight Weight_N Weight_Mean
Weight 19 100.02631579
Weight_
StdDev Height_Min Height_Max
22.773933494 50.5 150
Solution, étape 1 : Une solution est de faire un PROC TRANSPOSE pour un résultat sous la forme ci-dessous.
_NAME_ _LABEL_ COL1
Height_N N 19.000
Height_Mean Mean 62.337
Height_StdDev Std Dev 5.127
Height_Min Minimum 51.300
Height_Max Maximum 72.000
Weight_N N 19.000
Weight_Mean Mean 100.026
Weight_StdDev Std Dev 22.774
Weight_Min Minimum 50.500
Weight_Max Maximum 150.000
Dans la sortie brute de l’ODS OUTPUT, les variables commencent soit par HEIGHT, soit par WEIGHT (soit par VNAME ne m’intéresse pas ici). Il s’agit de transposer toutes ces variables. Il faut donc toutes les lister. Par soucis de clarté et de simplicité, on peut faire appel à une version abrégée : la racine commune des variables suivie de deux points.
proc transpose data=exemple1 out=exemple1;
var height: weight:;
run;
Solution, étape 2 : Pour retrouver une présentation semblable à celle d’un PROC MEANS envoyé dans la fenêtre OUTPUT, il faut transposer de nouveau. Auparavant, il faut créer une variable distinguant la variable HEIGHT de la variable WEIGHT.
var_name N Mean Std_Dev Minimum Maximum
Height 19 62.337 5.1271 51.3 72
Weight 19 100.026 22.7739 50.5 150
Créer une variable nommée VAR_NAME prenant soit la valeur HEIGHT soit la valeur WEIGHT.
- La fonction SCAN récupérera, dans une variable nommée VAR_NAME, le premier mot de la variable _NAME_ après avoir précisé que chaque mot est séparé par un trait bas (underscore).
- La longueur de la variable est définie explicitement au cas où certains noms de variables seraient supérieurs à 8 et donc tronqués.
- Cette longueur est définie avant l’instruction SET pour que la variable VAR_NAME apparaisse en premier.
data exemple1 (drop=_name_);
length var_name $12;
set exemple1;
var_name=scan(_name_,1,‘_’);
run;
Il est alors possible de faire pivoter le data set. Une ligne est créée pour HEIGHT et une autre pour WEIGHT, c’est-à-dire pour chaque nouvelle valeur de VAR_NAME. Chaque colonne prend le nom contenu dans la variable _LABEL_.
proc transpose data=exemple1 out=exemple1 (drop=_name_);
by var_name;
id _label_;
run;
L’instruction BY : Dans le cas du PROC MEANS, on ne rencontre pas de difficulté particulière liée à l’instruction BY. Au lieu d’avoir une ligne dans le fichier de sortie, on a autant de lignes que de valeurs dans la variable de l’instruction BY. Dans notre exemple, on a donc deux lignes avec une instruction BY SEX. Vous pouvez retrouver le code pour la transposition en fin d’article pour obtenir la sortie suivante :
Sex=F
var_name N Mean Std_Dev Minimum Maximum
Height 9 60.5889 5.0183 51.3 66.5
Weight 9 90.1111 19.3839 50.5 112.5
Sex=M
var_name N Mean Std_Dev Minimum Maximum
Height 10 63.91 4.9379 57.3 72
Weight 10 108.95 22.7272 83.0 150
3. Sélectionner ou exclure certaines sorties ou toute les sorties (ODS EXCLUDE, SELECT, LISTING)
L’instruction ODS LISTING CLOSE suspend l’envoie de toutes les sorties dans la fenêtre OUTPUT. L’ODS EXCLUDE interrompt un sous-ensemble ou toutes les sorties générées par la procédure. A l’inverse, l’ODS SELECT retient les sorties. A vous de voir si vous avez plus vite fait de lister les sorties à garder ou celles à exclure.
Quelques sorties : Pour sélectionner ou exclure quelques sorties en particulier, il suffit d’ajouter leur nom, trouvés au préalable avec ODS TRACE ON, séparé par un espace dans l’instruction. Cela est pratique pour des procédures générant beaucoup de sorties comme PROC UNIVARIATE.
Toutes les sorties : Pour faire la même chose sur toutes les sorties, on utilise ALL et NONE avec ODS EXCLUDE et ODS SELECT.
*Exemple 1 : Proc Means;
ods exclude all; *ods select none; *ods listing close;
proc means data=sashelp.class;
var height weight;
ods output summary=exemple1;
run;
ods exclude none; *ods select all; *ods listing;
Note : Toutes les explications couvertes dans cet article s’appliquent aussi à la procédure PROC SUMMARY.
Annexe : Détails du programme s’appliquant au second exemple
*Exemple 2 : Proc MEANS et l’instruction BY;
proc sort data=sashelp.class out=class;
by sex;
run;
proc means data=class;
by sex;
var height weight;
ods output summary=exemple2;
run;
proc transpose data=exemple2 out=exemple2;
by sex;
var height: weight:;
run;
data exemple2 (drop=_name_);
length var_name $12;
set exemple2;
var_name=scan(_name_,1,‘_’);
run;
proc transpose data=exemple2 out=exemple2 (drop=_name_);
by sex var_name;
id _label_;
run;
proc print data=exemple2 noobs;
by sex;
run;

Fini le Moyen-Age pour compter les mots
février 20, 2008
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;