Annonce

Bienvenue sur le site support de mes ouvrages d'introduction à SAS

La 4ème édition de mon ouvrage est disponible depuis le 11 avril 2019 !

Où trouver cet ouvrage ?


#1 17-11-2020 09:45:29

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

maudit fichier Excel !!!

encore une histoire tirée de faits réels...

de deux faits réels en fait...

Caroline m'a envoyé un fichier Excel avec lequel j'ai eu quelques difficultés et Ibrahima m'a contacté pour un problème qu'il rencontrait et qui avait aussi pour origine un fichier Excel.

Je vais concentrer les deux problèmes dans ce petit exercice...

Je dispose d'un classeur Excel avec lequel j'ai bien des misères....

ce fichier peut être téléchargé en cliquant sur ce lien

Comme je souhaite manipuler avec SAS les données contenues dans ce classeur, j'ai exécuté cette instruction :

Code:

libname test xlsx "c:/intro_sas/fichiers/maudit.xlsx";

évidemment, dans mon journal, tout semble bien aller :

Code:

2895  libname test xlsx "C:\intro_sas\fichiers\maudit.xlsx";
NOTE: Libref TEST was successfully assigned as follows:
      Engine:        XLSX
      Physical Name: C:\Users\leo_l\Documents\poubelle\maudit.xlsx

premier problème

Le premier onglet contient deux variables : email et type. Je souhaite afficher l'observation relative à l'email client_B@quinexistepas.com.
cette adresse email existe, aucun doute à ce sujet (vous pourrez vérifier en ouvrant le classeur Excel).

j'exécute donc le programme suivant :

Code:

proc print data=test.feuil1;
   where email="client_B@quinexistepas.com";
run;

et je n'obtiens aucun résultat.... dans mon journal, j'ai ce message :

Code:

NOTE: Access by observation number not available. Observation numbers will be counted by PROC PRINT.
NOTE: The import data set has 12 observations and 2 variables.
NOTE: No observations were selected from data set TEST.feuil1.
NOTE: There were 0 observations read from the data set TEST.feuil1.
      WHERE email='client_B@quinexistepas.com';
NOTE: PROCEDURE PRINT a utilisé (Durée totale du traitement) :
      real time           0.00 seconds
      cpu time            0.01 seconds

les deux premières notes ne doivent pas vous inquiéter, elles ne sont pas la cause de cette première difficulté...

vous ne me croyez pas ?

Code:

data maudit;
   set test.feuil1;
run;

proc print data=maudit;
   where email="client_B@quinexistepas.com";
run;

et vous n'aurez pas non plus de résultat.... pourtant, si vous remplacez = dans l'instruction WHERE par CONTAINS, vous obtenez bien un résultat...

Code:

proc print data=maudit;
   where email contains "client_B@quinexistepas.com";
run;

le résultat :
http://www.sas-sr.com/img/maudit.png

j'ai donc deux questions :
1- pourquoi ?
2- et comment corrige t'on le problème pour que le programme suivant fonctionne et donne le résultat escompté :


Code:

proc print data=maudit;
   where email="client_B@quinexistepas.com";
run;

second problème

pour des raisons qui n'appartiennent qu'à moi, j'ai besoin de créer un fichier TXT contenant les observations de la table maudite. J'ai donc rédigé ce programme (classique...) :

Code:

data _null_;
   set test.feuil1;
   file "C:\intro_sas\fichiers\maudit.txt";
   put email @30 type ;
run;

(j'ai indiqué un @30 dans mon instruction PUT parce que je souhaite créer un fichier TXT formaté colonne)

Mon journal m'indique que les choses semblent s'être bien passées :

Code:

2904  data _null_;
2905     set test.feuil1;
2906     file "C:\intro_sas\fichiers\maudit.txt";
2907     put email @30 type ;
2908  run;

NOTE: The file "C:\intro_sas\fichiers\maudit.txt" is:
      Nom du fichier=C:\intro_sas\fichiers\maudit.txt,
      RECFM=V,LRECL=32767,
      Taille de fichier (octets)=0,
      Modifié(e) le=17 novembre 2020 10 h 06,
      Heure de création=17 novembre 2020 10 h 06

NOTE: The import data set has 12 observations and 2 variables.
NOTE: 12 records were written to the file "C:\intro_sas\fichiers\maudit.txt".
      The minimum record length was 30.
      The maximum record length was 42.
NOTE: There were 12 observations read from the data set TEST.feuil1.
NOTE: DATA statement a utilisé (Durée totale du traitement) :
      real time           0.02 seconds
      cpu time            0.00 seconds

et j'ouvre mon fichier TXT pour vérifier qu'effectivement, tout va bien :

Code:

client_A@quinexistepas.com   super
client
client_B@quinexistepas.com   client
moyen
client_C@quinexistepas.com   client
bon
client_D@quinexistepas.com   super
client
client_E@quinexistepas.com   client
moyen
client_F@quinexistepas.com   client
bon
client_G@quinexistepas.com   super
client
client_H@quinexistepas.com   client
moyen
client_I@quinexistepas.com   client
bon
client_J@quinexistepas.com   super
client
client_K@quinexistepas.com   client
moyen

fatalitas !

et j'ai deux nouvelles questions (identiques en fait aux deux précédentes...):
1- pourquoi ?
2- et comment corrige t'on je problème pour que mon programme fonctionne et donne le résultat escompté : un fichier TXT dans lequel chaque observation n'est présentée que sur une ligne


amusez vous bien

Hors ligne

 

#2 Hier 12:41:39

SAS-SR
Administrateur
Lieu: Université d'Orléans
Date d'inscription: 01-09-2008
Site web

Re: maudit fichier Excel !!!

Attaquons nous aux deux premières questions posées liées à l'impossibilité d'avoir un résultat quand le programme suivant est exécuté :

Code:

proc print data=test.feuil1;
   where email="client_B@quinexistepas.com";
run;

pourquoi est ce que ça ne marche pas ?
réponse simple : parce que la modalité de EMAIL n'est jamais égale à client_B@quinexistepas.com

vous me direz :
"ah... pourtant, quand on regarde la modalité, on dirait bien qu'elle est égale à cette valeur pour la seconde observation !"

et je vous répondrai : "il ne faut JAMAIS croire ce que l'on voit quand on regarde une table SAS"

Ceux qui ont lu mes bouquins le savent...

"alors à quoi est égale cette modalité ?"

regardons cela au moyen du programme suivant :

Code:

libname lib xlsx "C:\intro_sas\fichiers\maudit.xlsx";

data maudit;
   set lib.feuil1;
   if _n_=2 then do ;
      do i=1 to length(email);
         lettre=substr(email,i,1);
         ascii=rank(lettre);
         put lettre= ascii=;
      end;
   end;
drop lettre ascii;
run;

ce programme permet de voir le code ASCII associées à chacun des caractères de la modalité d'EMAIL pour la seconde observation.

vous obtenez dans votre journal le résultat suivant :

Code:

lettre=c ascii=99
lettre=l ascii=108
lettre=i ascii=105
lettre=e ascii=101
lettre=n ascii=110
lettre=t ascii=116
lettre=_ ascii=95
lettre=B ascii=66
lettre=@ ascii=64
lettre=q ascii=113
lettre=u ascii=117
lettre=i ascii=105
lettre=n ascii=110
lettre=e ascii=101
lettre=x ascii=120
lettre=i ascii=105
lettre=s ascii=115
lettre=t ascii=116
lettre=e ascii=101
lettre=p ascii=112
lettre=a ascii=97
lettre=s ascii=115
lettre=. ascii=46
lettre=c ascii=99
lettre=o ascii=111
lettre=m ascii=109
lettre=  ascii=160

tiens.... tout semble être correct sauf... le dernier caractère... on dirait un blanc mais c'est en fait le caractère ASCII 160.

on se renseigne un peu et on découvre qu'il s'agit en réalité d'un blanc insécable - la caractère ASCII pour le blanc, c'est 32.

Dans un classeur EXCEL, si votre modalité contient des blancs à droite, lorsque vous lisez votre classeur Excel au moyen de SAS, ces blancs sont éliminés. Ça n'est pas le cas des blancs insécables.

Le problème de ces blancs insécables n'est pas un problème que j'invente de toute pièce et qui est lié uniquement à SAS : c'est relativement courant et ça ne concerne pas que SAS (pour vous en convaincre faites une recherche "Excel Ascii 160").

que faire ? supprimer ces espaces insécables !

Code:

data maudit(drop=i j);
   set maudit;
   array all{*} _character_;
   do i=1 to dim(all);
      do j=1 to length(all{i});
         all{i}=tranwrd(all{i},byte(160),'');
         all{i}=strip(all{i});
      end;
   end;
run;

la fonction BYTE(160), sorte "d'inverse" de RANK, permet de renvoyer à SAS, en second argument de TRANWRD, le caractère espace insécable que l'on souhaite remplacer par "rien".

J'ai utilisé ici TRANWRD mais on pouvait tout à fait utiliser COMPRESS :

Code:

         all{i}=compress(all{i},byte(160));

et maintenant, pourquoi utiliser STRIP dans l'instruction qui suit notre TRANWRD ?

Si les blancs à droite sont supprimés lorsque vous lisez un classeur Excel au moyen de SAS, ça n'est pas le cas avec les blancs à gauche... au moyen de STRIP, nous les supprimons.

Si maintenant, vous exécutez le programme suivant :

Code:

proc print data=maudit;
   where email="client_B@quinexistepas.com";
run;

vous aurez bien un résultat.

Avons nous régler l'ensemble des problèmes liés à ce classeur Excel ?

et bien non... ce saut de ligne qui apparaît lorsqu'on veut créé un fichier TXT est toujours là... mais maintenant que vous avez la méthode, vous saurez sûrement le régler...

à suivre...

Hors ligne

 

Pied de page des forums

Propulsé par FluxBB
Traduction par FluxBB.fr
Flux RSS