SAS: дополнительные параметры для импорта proc - неверный формат переменной

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

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

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

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


person Jonas Lundin    schedule 07.11.2019    source источник
comment
Вы не можете прочитать 301185964728506014850593 как числовое в SAS без потери информации   -  person Lee    schedule 07.11.2019
comment
Какой у вас клиент SAS? Диспетчер отображения, руководство для предприятий или SAS Studio?   -  person Richard    schedule 07.11.2019
comment
Я использую руководство для предприятий.   -  person Jonas Lundin    schedule 07.11.2019


Ответы (2)


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

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

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

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

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

person Amir    schedule 07.11.2019

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

Из раздела "

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    213            3
 4                    2,097,152    221            6
 5                  536,870,912    229            8
 6              137,438,953,472    237           11
 7           35,184,372,088,832    245           13
 8        9,007,199,254,740,992    253           15

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

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

Из файла документации " "Файлы с разделителями

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

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

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

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

Итак, шаги будут

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

Пример:

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

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
person Richard    schedule 07.11.2019