Импорт плоского файла с разделителями строк и столбцов
Я импортирую плоский файл.txt с разделителями строк и столбцов. Проблема заключается в том, что разделитель строк используется для уменьшения размера файла, поэтому часто остальные столбцы пропускаются. Другая проблема заключается в том, что длина самого длинного символа неизвестна, и поэтому, если эта строка символов усекается, мы теряем разделитель, и вся структура разваливается.
Явный пример проблем, с которыми я сталкиваюсь, включает
TXT-файл
Var1'~'Var2'~'Var3'~'Var4'~'Var5'~'Var6'#@#@'
1'~''#@#@'
This is going to be a really long string as an example of a situation where the long string is very large and so the truncated string does not indicate a delimiter and we lose data '#@#@'
1'~' 2'~' 3'~' 4'~' 5'~' 6'#@#@'
1'~' 2'~' 3'~''#@#@'
У меня много проблем при попытке импортировать эти данные по ряду причин:
установка очень большой длины для символьных переменных делает процесс импорта очень трудоемким, и мы не знаем длину самого длинного символьного var, поэтому каждая итерация занимает больше времени
Я еще не нашел способ иметь дело как с столбцом, так и с разделителем строк, когда структура означает, что следующая строка может быть сигнализирована до того, как будут заполнены все столбцы, т.е. не может просто создать дополнительный столбец для разделителя строк и удаления Это.
Код SAS, для которого я пробовал:
data want;
infile "file-location" dlmstr = "#@#@" dsd recfm = F lrecl=10000000000;
informat var $200.
input var $ @@;
run;
Любой опыт и понимание очень ценится.
1 ответ
Если у вас есть одна запись на строку, то просто используйте missover
или же truncover
вариант на инфиле; это скажет SAS прекратить чтение после того, как оно достигнет EOL. Вам придется иметь дело со странным конечным разделителем только в той мере, в которой он вызовет ошибку, если вы попытаетесь прочитать его в числовое значение; Вы могли бы попытаться сначала удалить строку в предварительной обработке.
data want;
infile "yourfile-location" dlmstr="'~'" dsd lrecl=32767 truncover;
input @;
_infile_ = tranwrd(_infile_,"'#@#@'"," ");
input var1 var2 var3 var4 var5 var6;
run;
То, как вы это написали, также может сработать, если вышесказанное по какой-то причине не сработало; в основном, читается в строке дважды с двумя различными параметрами разделителя, один раз с помощью ''#@#@'' dlmstr, затем с помощью ''~'' dlmstr. Или вместо того, чтобы прочитать его дважды, прочитать один раз с первым, а затем проанализировать со вторым.
data want;
infile "yourfile-location" dlmstr="'#@#@'" dsd lrecl=32767;
input @;
array var[6] var1-var6;
do _i = 1 to countc(_infile_,"~")+1;
var[_i] = scan(_infile_,_i,"~");
end;
run;
Вышеприведенное не является идеальным, поскольку оно не имеет отношения к этим кавычкам вокруг разделителя, но вы можете выяснить это в зависимости от деталей - является ли эта кавычка безопасной, чтобы просто сжать полностью перед вводом, или вам нужно сделать какая-нибудь модная работа с SUBSTR?
Что касается длины строковой переменной, то, скорее всего, потребуется время для записи файла. использование options compress=char;
чтобы включить сжатие набора данных, при условии, что ваше конечное использование этих файлов совместимо с этим (если вы просто запускаете на них код SAS, так и должно быть). Тогда он не будет пытаться выписать полную переменную длину. Если это не поможет, вам, возможно, придется пересмотреть структуру набора данных, чтобы избежать этой проблемы - вам нужно будет задать отдельный вопрос с гораздо большим количеством деталей, чтобы найти там лучшее решение.