Программирование SAS - Шаг DATA - Проблема разбора текста в набор данных SAS

Я пытаюсь создать набор данных SAS из текстового файла. Текстовый файл показывает данные в таком формате:

-HADER HEADER HEADER

-HADER HEADER HEADER

April SpringRace Мужской

$$$$$$$$$$$$$$$$$$$$

Имя Возраст Государство / это названия в текстовом файле /

$$$$$$$$$$$$$$$$$$$$

Джон Смит 30 CA

Марк Доу 49 TX

Май SpringRace2 Женский

$$$$$$$$$$$$$$

Имя Возраст Государство

$$$$$$$$$$$$$$

Бетти Уайт 50 ME

Джейн Смит 37 Нью-Йорк


Проблема, с которой я сталкиваюсь при выполнении шага данных, заключается в том, чтобы: пропустить переменные строки заголовков, а затем собрать данные "события" перед тем, как ****** заголовки ******* в качестве переменных, затем пропустить заголовки и назначение переменных для реальных людей. Это похожий формат во всем огромном текстовом файле. Пожалуйста, кто-нибудь может указать мне правильное направление?

Я экспериментировал: данные work.test; infile c:\tester dlm=', $' missover; вход / / / Месяц 15 $. EventName $15. Пол 6 долларов. (Это то, где я застреваю, так как не знаю, как пропустить "Name Age State" в текстовом файле и просто назначить переменные для "John Smith 30 CA" и т. Д.);

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

Спасибо

2 ответа

Решение

Я думаю, что использование указателя столбца @'my_char_string' в выражении INPUT поможет вам, если заголовки, которые разделяют значения данных, всегда повторяются, и вы знаете, что это такое. Например:

INFILE mydatafile FLOWOVER FIRSTOBS=2;

Входной месяц $ race $ sex $ @'State' first_name $ last_name $ address $;

Опция FIRSTOBS=2 в операторе INFILE пропускает строку HEADER HEADER..., а опция FLOWOVER указывает SAS продолжать поиск данных в следующей строке, в частности для @'State'. Вам может потребоваться указать дополнительные параметры и форматирование, в зависимости от формата входного файла, разделителей и т. Д.

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

data test1;
    length test $20 month $20 event $20 gender $20 firstname $20 lastname $20 state $2;
    infile "test1.txt" DLM=' $' FIRSTOBS=5; 

    retain month event gender;   * Keep these values from last readin;

    input test $ @;    /* Read in the first word in the data line being 
                         read into test var, and stay on this line for 
                         now (with @)*/

    if strip(test) in('April', 'May') then do; /* If test var contains month,
                                                 then read in all of the variables, 
                                                 and skip the name/age/state titles row*/
        input @1 month $ event $ gender $ @'State' firstname $ lastname $ age state $ ;
    end;
    else do;    /* Otherwise, the data line being read in should contain 
                  only names, age and state, so read in those values only.
                  The month, event and gender values will be kept the same 
                  by the retain statement above.*/ 
        input @1 firstname $ lastname $ age state $ ;
    end;
    drop test; /* Comment out this drop statement to see whats in test var*/
run;

Этот код будет работать с различным количеством участников на событие. Но месяц не может быть пропущен, чтобы этот код работал.

Полезный совет: чтобы увидеть, что находится в текущей строке данных, читаемой SAS, попробуйте добавить

 put _INFILE_;

после заявления INFILE. Он напечатает строки данных в вашем журнале так, как их видит SAS.

Надеюсь, вы уже давно решили свою проблему, но вот еще одно предложение. Использование завершающего @ в операторе ввода позволяет применить второй оператор ввода и будет предпочтительным решением. Это решение на самом деле не использует трейлинг @, но я оставил его на ваше усмотрение в будущем.

DATA test;
INFILE 'stacktest.txt' lrecl=200 missover;
length n1 n2 n3 n4 $20. ;
input @1 c1 $1. @1 c2 $2. @1 c5 $5. @1 lne & $75. @ ;
keep month event gender fname lname age state;
if c1 = ' ' then return;
if c1 = '-' then return;
if c1 = '$' then return;
if c5 = 'Name' then return;

n1 = scan(lne, 1);
n2 = scan(lne, 2);
n3 = scan(lne, 3);
n4 = scan(lne, -1);

if ( n3 eq 'Male' or n3 eq 'Female')  then do;
   month = n1 ;
   event = n2;
   gender = n3  ;
     return;
     end;
 else do ;
*  input  fname $ lname $ age  state $ ;
fname = n1 ;
lname = n2 ;
age   = n3 ;
state = n4 ;
     output;
      end;
 retain month event gender;
run;
Другие вопросы по тегам