Импорт плоского файла с разделителями строк и столбцов - PullRequest
0 голосов
/ 16 октября 2018

Я импортирую плоский текстовый файл с разделителями строк и столбцов.Проблема заключается в том, что разделитель строк используется для уменьшения размера файла, поэтому часто остальные столбцы пропускаются.Другая проблема заключается в том, что длина самого длинного символа неизвестна, и поэтому, если эта строка символов усекается, мы теряем разделитель, и вся структура разваливается.

Явный пример проблем, с которыми я сталкиваюсь, включает

.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'~''#@#@'

У меня много проблем при попытке импортировать эти данные по ряду причин:

  1. установкаочень большая длина символьных переменных делает процесс импорта очень трудоемким, и мы не знаем длины самого длинного символьного переменной, поэтому каждая итерация занимает больше времени

  2. Я еще не нашелспособ работы как с разделителем столбцов, так и со строкой, когда структура означает, что следующая строка может быть сигнализирована до того, как будут заполнены все столбцы, т.е. не может просто создать дополнительный столбец для разделителя строк и удалить его.

Код SAS, для которого я пробовал:

data want;
infile "file-location" dlmstr = "#@#@" dsd recfm = F lrecl=10000000000;
informat var $200.
input var $ @@;
run;

Любой опыт и понимание приветствуются.

1 Ответ

0 голосов
/ 16 октября 2018

Если у вас есть одна запись на строку, тогда просто используйте опцию missover или truncover на infile;это скажет 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, так и должно быть).Тогда он не будет пытаться выписать полную переменную длину.Если это не помогло, возможно, вам придется пересмотреть структуру набора данных, чтобы избежать этой проблемы - вам нужно будет задать отдельный вопрос с гораздо более подробной информацией, чтобы найти там лучшее решение.

...