
Lire des données d’un fichier .TXT sans perdre d’information (les options d’INFILE)
novembre 7, 2008L’accès à des données contenues dans un fichier externe du type .TXT se fait sous SAS par l’intermédiaire d’une étape data et de l’instruction INFILE. Plusieurs options sont possibles pour cette instruction. Il est important de connaître les forces et faiblesses de chacune afin de faire le bon choix. Cet article vous présentera dans un premier temps le fichier .TXT qui servira d’exemple. En premier lieu, il sera appelé avec l’option FLOWOVER, l’option par défaut. Puis, cela sera le tour des options TRUNCOVER et MISSOVER/PAD.
1. Aperçu sur les données contenu dans le fichier .TXT
Afin de montrer les nuances entre les options FLOWOVER, TRUNCOVER et MISSOVER, un fichier EG_INFILE.TXT est créé. Ce fichier contient les données pour deux variables caractères CNTRY (country) et CNT (count).
Dans l’aperçu qui suit, j’ai remplacé les espaces par des points afin de vous puissiez visualiser la différence que peuvent créer certains espaces.
- La première ligne contient 2 caractères
- Les seconde et troisième lignes contiennent 12 caractères
- L’avant dernière ligne n’en contient que 4
- La dernière en contient 12 si on inclus les espaces de fin.
Note : « e.g. » est la version raccourcie de « example » en anglais. C’est donc notre équivalent de « ex ».
IT CA.12....... BE.123456789 KR. MY.2 FI.1........
Le choix du FILENAME : Par choix, je crée un mot SASREF qui désigne le chemin d’accès au fichier EG_INFILE.TXT. Cela évitera d’avoir à recopier le chemin dans chaque étape data. Toute mise à jour ou correction du chemin d’accès se fera en une seule fois évitant tout oubli.
filename sasref 'C:/sasref/eg_infile.txt';
Note : Il est important de définir une longueur pour les variables caractères. Sinon les variables ayant plus de 8 caractères sont tronquées. Dans notre cas, la valeur 123456789 deviendrait 12345678.
2. FLOWOVER, l’option par défaut
Par défaut, SAS applique l’option FLOWOVER avec une instruction INFILE. Ainsi l’instruction INFILE mise en commentaire, en ajoutant une étoile en tête d’instruction, donnerait le même résultat que celle active.
data eg_flowover; infile sasref; *infile sasref flowover; length cntry $2 cnt $9; input cntry $ cnt $; run;
L’aperçu qui suit montre très clairement que SAS continu sa lecture sur la ligne suivante s’il n’a pas trouvé une valeur pour chaque variable dans la ligne actuelle.
- Créer la première ligne d’observations : En ligne 1, il manque une valeur pour CNT. SAS va en ligne deux et récupère la première valeur. Il ignorera toutes les valeurs qui peuvent exister sur le reste de la ligne. Il lui a donc fallu deux lignes en entrée pour créer une ligne en sortie.
- Créer la seconde ligne d’observations : après avoir lu les deux premières lignes, SAS passe à la troisième ligne pour créer la seconde ligne d’observations. Il trouve son bonheur ici puisqu’il y a une valeur par variable.
- Créer la troisième ligne d’observations : à la ligne suivante, il manque de nouveau une valeur. SAS assigne la valeur KR à la variable CNTRY. Mais ne trouvant pas de valeur pour la variable CNT, il passe à la ligne suivante et trouve la valeur MY.
- Créer la quatrième et dernière ligne d’observations : il ne reste a SAS plus qu’une ligne de disponible dans le fichier d’entrée. Cette ligne contient une observation par variable. SAS est content avec.
cntry cnt IT CA BE 123456789 KR MY FI 1
3. L’option TRUNCOVER empêche le passage à la ligne et ne se formalise pas des longueurs
L’option TRUNCOVER palie à ce problème en empêchant à SAS d’aller voir à la ligne suivante
data eg_truncover; infile sasref truncover; length cntry $2 cnt $9; input cntry $ cnt $; run;
Le résultat est comme escompté :
cntry cnt IT CA 12 BE 123456789 KR MY 2 FI 1
4. L’option MISSOVER empêche le passage à la ligne
Les limites de l’option MISSOVER avec un INFILE : L’option MISSOVER est une autre option possible de l’instruction INFILE. Elle présente néanmoins une limite due à des espaces.
data eg_missover; infile sasref missover; length cntry $2 cnt $9; input cntry $ cnt $; run;
Dans l’exemple, la valeur de CNT (2) quand CNTRY=MY disparaît, alors quela valeur de CNT (1) quand CNTRY=FI reste. Alors que la Qu’est ce qui a provoqué cela ?
Vous souvenez vous de la remarque concernant les espaces en fin de ligne dans la première section de cette article. SAS recherche 9 caractères pour créer une valeur pour CNT. Hors quand CNTRY=MY, il n’en trouve qu’un. Cela ne le satisfait pas. Comme, avec MISSOVER, il ne peut pas aller voir sur la ligne d’après. Il se contente de mettre une valeur manquante.
cntry cnt
IT
CA 12
BE 123
KR
MY
FI 1
L’équivalent de TRUNCOVER : L’option MISSOVER en combinaison avec l’option PAD fournira le même résulat que l’option TRUNCOVER. Autant donc utiliser un seul mot en la personne de TRUNCOVER.
data eg_missover_pad; infile sasref missover pad; length cntry $2 cnt $9; input cntry $ cnt $; run;
Le cas particulier du DATALINES : MISSOVER avec un DATALINES ne rencontre pas le problème des blancs de fin de ligne manquants.
data eg_missover; infile datalines missover; length cntry $2 cnt $9; input cntry $ cnt $; datalines; IT CA 12 BE 123456789 KR MY 2 FI 1 ; run;
Conclusion
Nous avons vu un cas particulier de l’instruction INFILE : lecture d’un fichier dans lequel chaque ligne est sensée représenter une ligne d’observations.
Par défaut, SAS recherche autant d’emplacements (texte ou espaces) dans le fichier qu’il lit que celui donné par la longueur d’une variable. Faute de quoi SAS jetera un coup d’oeil à la ligne suivante (FLOWOVER) ou ignorera certaines valeurs (MISSOVER) selon l’option indiquée dans l’instruction INFILE.
L’option TRUNCOVER répond aux deux problèmes (passage à la ligne et manque de place sur une ligne). Il est donc judicieux de privilégier l’option TRUNCOVER sur MISSOVER pour ce problème précis.
Bonjour,
Il me semble qu’il y a une erreur :
data eg_missover;
infile sasref missover;
length cntry $2 cnt $9;
input cntry $ cnt $;
run;
donne selon l’article :
cntry cnt
IT
CA 12
BE 123
KR
MY
FI 1
Il me semble que la vrai sortie est :
cntry cnt
IT
CA 12
BE 123456789
KR
MY
FI 1
Nous avons vu un cas particulier de l’instruction INFILE : lecture d’un fichier dans lequel chaque ligne est **Censée** représenter une ligne d’observations.
Petite faute, mais très bon blog !