Los datos se generan directamente en el script a través de un paso DATA _NULL_, que escribe un archivo de texto delimitado con delimitadores faltantes intencionales. Este archivo temporal se utiliza posteriormente como fuente para los pasos DATA de lectura y corrección.
1 Bloque de código
DATA STEP Data
Explicación : Este bloque inicializa una referencia de archivo (FILENAME) a un archivo de texto llamado 'osbbb.txt' en 'C:\TEMP'. Luego, se utiliza un paso DATA _NULL_ para crear y escribir líneas de datos en este archivo. El contenido incluye una línea de encabezado y varias líneas de datos, algunas de las cuales tienen delimitadores faltantes intencionalmente (por ejemplo, 'Gannet~22JUL2018~Y' le falta el segundo delimitador entre 'Gannet' y '22JUL2018'), simulando así un escenario de datos corruptos para las pruebas posteriores.
¡Copiado!
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 Bloque de código
DATA STEP Data
Explicación : Este paso DATA intenta leer el archivo 'MISSING' creado previamente. La instrucción INFILE utiliza el delimitador tilde (~), la opción DSD para tratar los delimitadores consecutivos como valores faltantes, FIRSTOBS=2 para ignorar el encabezado, y TRUNCOVER para evitar errores cuando las líneas son más cortas de lo esperado. Sin embargo, debido a los delimitadores faltantes que no son delimitadores consecutivos sino desplazamientos, este bloque demuestra que la lectura fallará para los registros corruptos, lo que resultará en datos asignados o truncados incorrectamente.
¡Copiado!
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 Bloque de código
DATA STEP Data
Explicación : Este paso DATA propone una primera solución para corregir los delimitadores faltantes. La instrucción 'input @;' lee la línea completa en la variable automática _INFILE_ sin analizarla. Luego usa la función SCAN para verificar el contenido supuesto de la cuarta columna ('field4'). Si 'field4' no es 'Y' o 'N', indica un delimitador faltante. En este caso, el código encuentra el primer delimitador (FIND) e inserta un tilde ('~') adicional después de él manipulando la cadena _INFILE_ con SUBSTR. Finalmente, una segunda instrucción INPUT vuelve a leer la línea corregida de _INFILE_ para un análisis correcto. Las variables temporales DLM1AT y field4 se eliminan posteriormente (DROP).
¡Copiado!
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 Bloque de código
DATA STEP Data
Explicación : Este paso DATA ofrece una solución más elegante y concisa utilizando expresiones regulares. Al igual que el bloque anterior, 'input @;' lee la línea completa en _INFILE_. Luego se utiliza la función PRXCHANGE para buscar un patrón específico: el inicio de la cadena, seguido de una secuencia de 1 a 8 caracteres que no sean tilde, luego un tilde, capturando todo en el primer grupo de captura (\1). Luego busca un carácter que no sea tilde inmediatamente después del primer grupo de captura (\2). Si se encuentra este patrón (lo que indica un delimitador faltante entre el primer y el segundo campo), inserta un tilde entre los dos grupos de captura (\1~\2), corrigiendo así _INFILE_. La línea corregida se lee luego mediante la instrucción INPUT final.
¡Copiado!
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;
Este material se proporciona "tal cual" por We Are Cas. No hay garantías, expresas o implícitas, en cuanto a la comerciabilidad o idoneidad para un propósito particular con respecto a los materiales o el código contenidos en este documento. We Are Cas no es responsable de los errores en este material tal como existe ahora o existirá, ni We Are Cas proporciona soporte técnico para el mismo.
Información 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 y todos los demás nombres de productos o servicios de SAS Institute Inc. son marcas registradas o marcas comerciales de SAS Institute Inc. en los EE. UU. y otros países. ® indica registro en los EE. UU. WeAreCAS es un sitio comunitario independiente y no está afiliado a SAS Institute Inc.
Este sitio utiliza cookies técnicas y analíticas para mejorar su experiencia.
Saber más.