SAS: дополнительные параметры для импорта процедур - неверный формат переменной - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь импортировать несколько файлов .txt в SAS. Значения разделены точками с запятой, и каждый файл имеет несколько миллионов наблюдений. У меня проблема при импорте файла, одна из переменных получает неправильное форматирование. Исходное значение для наблюдения является случайным числом (хотя все приблизительно из 20-25 цифр), и для одного объекта может быть что-то вроде 301185964728506014850593. При импорте SAS, по какой-то причине, читается как (числовое, правильно, но не важно) 3.0118596E23. Как я могу заставить SAS читать именно то, что находится в файле .txt?

Поиск документации не принес никаких результатов, так как было найдено совсем немного дополнительных опций. Приведенный ниже код является стандартным кодом, который я использую для импорта файлов (использование смешанного = да, похоже, не помогает, и расширение гаданий не меняет ничего, за исключением того, что я установил его на максимум, что просто приводит к краху всей системы).

proc import DATAFILE="W:FILE1.txt" OUT=FILE1 DBMS=dlm replace; delimiter=';'; guessingrows=100; run;

Когда это прочитано, я получаю сообщение об ошибке «ОШИБКА: Импорт неудачен. Подробности см. В журнале SAS». Однако файл импортируется, и я вижу, что все строки и переменные включены. Я просто хочу изменить формат или, возможно, переменную длину (вызвать идентификатор переменной) на этапе импорта proc. Это возможно?

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Чтобы иметь больший уровень контроля при чтении в файле необработанных данных, вы должны рассмотреть возможность использования шага данных, например:

data want;
   infile datalines4 dlm = ';' dsd;

   input
      id : $char25.
      v1 : $char10.
      v2 :       8.
   ;

   datalines4;
301185964728506014850593;abc;123
30118596472850601485059;abcd;1234
3011859647285060148505;abcde;12345
;;;;

Таким образом, вы можете указать идентификатор в качестве символа и т. Д. данные будут храниться, как представлено в файле.

0 голосов
/ 07 ноября 2019

Существует ограничение SAS на то, насколько большим может быть число и при этом сохраняется точное целочисленное представление. ( На основе двоичных пределов функций мантиссы и экспоненты в значениях с плавающей запятой двойной точности )

Из " SAS Companion для Windows "

Significant Digits and Largest Integer by Length for SAS Variables under Windows 

Length   Largest                     
in       Integer                                 Significant
Bytes    Represented              Exponential   Digits 
         Exactly                  Notation      Retained
------   -----------------------  -----------   -----------
 3                        8,192    2<sup>13</sup>            3
 4                    2,097,152    2<sup>21</sup>            6
 5                  536,870,912    2<sup>29</sup>            8
 6              137,438,953,472    2<sup>37</sup>           11
 7           35,184,372,088,832    2<sup>45</sup>           13
 8        9,007,199,254,740,992    2<sup>53</sup>           15

Невозможно напрямую указать форматы столбцов с помощью процедуры IMPORT.

Вы можете вызвать исходный код шага DATA, созданный процедурой, и изменить его.

Из файла документации " Ссылка на формат для процедур ИМПОРТ И ЭКСПОРТ " Файлы с разделителями

Обработка файлов с разделителями в SAS

Когда вы используете PROC IMPORT для чтения файла, разделенного запятыми, файла с разделителями табуляции или другого файла с разделителями, процедура по умолчанию выполняет следующие действия:

  • создает шаг DATA с помощью оператора INPUT
  • передает весь код компилятору шага DATA, который, в свою очередь, выполняет код.

Если вам нужно пересмотреть свой код после запуска процедуры, введите команду RECALL (или нажмите F4) для сгенерированного шага DATA. На этом этапе вы можете добавлять или удалять опции из оператора INFILE и настраивать операторы INFORMAT, FORMAT и INPUT для ваших данных.

Таким образом, шаги будут:

  1. Передать Proc IMPORT, который выводит ноль строк.
    Единственное, что требуется от этого шага, - это исходный код, сгенерированныйпроцедура
  2. Открытие нового окна редактирования (т. е. меню Вид / Расширенный редактор)
  3. Введите команду RECALL в командной строке (или меню Выполнить / восстановить последнюю отправку)
  4. Отредактируйте вызванный исходный код
    - Снимите ограничитель where=(1=0))
    - Измените INFORMAT с best32. на что-то вроде $32.
    - Удалите соответствующий FORMAT оператор
  5. Отправьте отредактированный код

Пример:

Создать образец набора данных со слишком большими целыми числами и IMPORT it

filename myfile temp;

data _null_;
  file myfile;
  put "one;two;three";
  put "1;2;3";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
  put "301185964728506014850593;301185964728506014850594;301185964728506014850595";
run;


proc import 
  file=myfile 
  dbms=dlm
  replace
  out=myimport(where=(1=0)    /* output limiter */
;
  delimiter=';';
run;

Напомним исходный код SAS, отредактируйте его и повторно отправьте

 /**********************************************************************
 *   PRODUCT:   SAS
 *   VERSION:   9.4
 *   CREATOR:   External File Interface
 *   DATE:      07NOV19
 *   DESC:      Generated SAS Datastep Code
 *   TEMPLATE SOURCE:  (None Specified.)
 ***********************************************************************/
    data WORK.MYIMPORT 
/*(where=(1=0))   */        /* <------ remove limiter */
;
    %let _EFIERR_ = 0; /* set the ERROR detection macro variable */
    infile MYFILE delimiter = ';' MISSOVER DSD lrecl=32767 firstobs=2 ;
       informat one $32. ;        /* <-------- change informats */
       informat two $32. ;
       informat three $32. ;
/*       format one best12. ;*/   /* <--------- remove format statements */
/*       format two best12. ;*/
/*       format three best12. ;*/
    input
                one
                two
                three
    ;
    if _ERROR_ then call symputx('_EFIERR_',1);  /* set ERROR detection macro variable */
    run;

Возвращает набор данных

Obs    one                         two                         three

 1     1                           2                           3
 2     301185964728506014850593    301185964728506014850594    301185964728506014850595
 3     301185964728506014850593    301185964728506014850594    301185964728506014850595
 4     301185964728506014850593    301185964728506014850594    301185964728506014850595
 5     301185964728506014850593    301185964728506014850594    301185964728506014850595
 6     301185964728506014850593    301185964728506014850594    301185964728506014850595
 7     301185964728506014850593    301185964728506014850594    301185964728506014850595
...