Les données sont générées directement dans le script via un DATA _NULL_ step, qui écrit un fichier texte délimité avec des délimiteurs manquants intentionnels. Ce fichier temporaire est ensuite utilisé comme source pour les DATA steps de lecture et de correction.
1 Bloc de code
DATA STEP Data
Explication : Ce bloc initialise une référence de fichier (FILENAME) vers un fichier texte nommé 'osbbb.txt' dans 'C:\TEMP'. Ensuite, un DATA _NULL_ step est utilisé pour créer et écrire des lignes de données dans ce fichier. Le contenu inclut une ligne d'en-tête et plusieurs lignes de données, dont certaines ont intentionnellement des délimiteurs manquants (par exemple, 'Gannet~22JUL2018~Y' manque le deuxième délimiteur entre 'Gannet' et '22JUL2018'), simulant ainsi un scénario de données corrompues pour les tests suivants.
Copié !
FILENAME MISSING 'C:\TEMP\osbbb.txt';
data _NULL_;
file MISSING;
put 'Animal~Mode~Date~Bird';
put 'Beaver~~09OCT2019~N';
put 'Gannet~22JUL2018~Y';
* ^-- missing delimiter;
put 'Peacock~~17DEC2017~Y';
put 'Robin~23FEB2019~Y';
* ^-- missing delimiter;
put 'Nuthatch~19APR2019~Y';
* ^-- missing delimiter;
run;
1
FILENAME MISSING 'C:\TEMP\osbbb.txt';
2
3
DATA _NULL_;
4
file MISSING;
5
put 'Animal~Mode~Date~Bird';
6
put 'Beaver~~09OCT2019~N';
7
put 'Gannet~22JUL2018~Y';
8
* ^-- missing delimiter;
9
put 'Peacock~~17DEC2017~Y';
10
put 'Robin~23FEB2019~Y';
11
* ^-- missing delimiter;
12
put 'Nuthatch~19APR2019~Y';
13
* ^-- missing delimiter;
14
RUN;
2 Bloc de code
DATA STEP Data
Explication : Ce DATA step tente de lire le fichier 'MISSING' créé précédemment. L'instruction INFILE utilise le délimiteur tilde (~), l'option DSD pour traiter les délimiteurs consécutifs comme des valeurs manquantes, FIRSTOBS=2 pour ignorer l'en-tête, et TRUNCOVER pour empêcher les erreurs lorsque les lignes sont plus courtes que prévu. Cependant, en raison des délimiteurs manquants qui ne sont pas des délimiteurs consécutifs mais des décalages, ce bloc démontre que la lecture échouera pour les enregistrements corrompus, entraînant des données incorrectement assignées ou tronquées.
Copié !
data missing;
infile MISSING dlm='~' DSD firstobs=2 truncover;
format Animal $8. Mode $5. Date DATE9. Bird $1.;
input Animal Mode Date:DATE9. Bird;
run;
1
DATA missing;
2
INFILE MISSING dlm='~' DSD firstobs=2 truncover;
3
FORMAT Animal $8. Mode $5. Date DATE9. Bird $1.;
4
INPUT Animal Mode Date:DATE9. Bird;
5
RUN;
3 Bloc de code
DATA STEP Data
Explication : Ce DATA step propose une première solution pour corriger les délimiteurs manquants. L'instruction 'input @;' lit la ligne complète dans la variable automatique _INFILE_ sans l'analyser. Il utilise ensuite la fonction SCAN pour vérifier le contenu supposé de la quatrième colonne ('field4'). Si 'field4' n'est pas 'Y' ou 'N', cela indique un délimiteur manquant. Dans ce cas, le code trouve le premier délimiteur (FIND) et insère un tilde ('~') supplémentaire après celui-ci en manipulant la chaîne _INFILE_ avec SUBSTR. Enfin, une seconde instruction INPUT relit la ligne corrigée à partir de _INFILE_ pour un parsing correct. Les variables temporaires DLM1AT et field4 sont ensuite supprimées (DROP).
Copié !
data fixed (drop=DLM1AT field4);
infile MISSING dlm='~' DSD firstobs=2;
format Animal $8. Mode $5. Date DATE9. Bird $1.;
input @;
length field4 $1;
field4 = scan(_INFILE_, 4, '~', 'M');
if field4 not in ('Y', 'N') then do;
DLM1AT = FIND(_INFILE_, '~');
_INFILE_ = SUBSTR(_INFILE_, 1, DLM1AT) ||
'~' || SUBSTR(_INFILE_, DLM1AT + 1);
end;
input Animal Mode Date:DATE9. Bird;
run;
1
DATA fixed (drop=DLM1AT field4);
2
INFILE MISSING dlm='~' DSD firstobs=2;
3
FORMAT Animal $8. Mode $5. Date DATE9. Bird $1.;
4
INPUT @;
5
LENGTH field4 $1;
6
field4 = scan(_INFILE_, 4, '~', 'M');
7
IF field4 not in ('Y', 'N') THENDO;
8
DLM1AT = FIND(_INFILE_, '~');
9
_INFILE_ = SUBSTR(_INFILE_, 1, DLM1AT) ||
10
'~' || SUBSTR(_INFILE_, DLM1AT + 1);
11
END;
12
INPUT Animal Mode Date:DATE9. Bird;
13
RUN;
4 Bloc de code
DATA STEP Data
Explication : Ce DATA step offre une solution plus élégante et concise en utilisant les expressions régulières. Comme le bloc précédent, 'input @;' lit la ligne complète dans _INFILE_. La fonction PRXCHANGE est ensuite utilisée pour rechercher un motif spécifique : le début de la chaîne, suivi d'une séquence de 1 à 8 caractères non-tilde, puis un tilde, capturant le tout dans le premier groupe de capture (\1). Il recherche ensuite un caractère non-tilde immédiatement après le premier groupe de capture (\2). Si ce motif est trouvé (ce qui signale un délimiteur manquant entre le premier et le deuxième champ), il insère un tilde entre les deux groupes de capture (\1~\2), corrigeant ainsi _INFILE_. La ligne corrigée est ensuite lue par l'instruction INPUT finale.
Copié !
data everythings_better_with_regex;
infile MISSING dlm='~' DSD firstobs=2;
format Animal $8. Mode $5. Date DATE9. Bird $1.;
input @;
_INFILE_ = PRXCHANGE('s/^([^~]{1,8}~)([^~])/, 1, _INFILE_);
input Animal Mode Date:DATE9. Bird;
run;
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.
Informations de Copyright : Paper 4839-2020
Read Before You Read: Reading, Rewriting & Re-Reading
Difficult Delimited Data in a Data Step
Appendix B - Complete Code for Missing Delimiters
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.