GREP-подобная функция для извлечения текста в SAS - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу получить определенный текст в столбце в файле SAS.

Файл хотел бы следующее:

Patient    Location    infoTxt
001        B           Admission Code: 123456 X
                       Exit Code: 98765W
002        C           Admission Code: 4567 WY
                       Exit Code: 76543Z
003        D           Admission Code: 67890 L
                       Exit Code: 4321Z

Я хочу получить только информацию после двоеточия для кода доступа и кода выхода и поместить их в свои собственные столбцы. «Коды» могут быть любой комбинацией букв, цифр и пробелов. Новые данные будут выглядеть следующим образом:

Patient    Location    AdmissionCode      ExitCode
001        B           123456 X            8765W
002        C           4567 WY             76543Z
003        D           67890 L             4321Z

Я не знаком с функциями в SAS, но, возможно, логика будет выглядеть примерно так:

data want;
  set have;
  do i = 1 to dim(infoTxt)

    AdmissionCode = substring(string1, regexpr(":", string) + 1);
    ExitCode = substring(string2, regexpr(":", string) + 1);

run;

В приведенном выше коде строка1 будет представлять первую строку текста в infoTxt, а строка2 будет представлять вторую строку текста infoTxt.

Ответы [ 4 ]

0 голосов
/ 06 сентября 2018

При условии, что у вас всегда одинаковый шаблон двоеточий и разрывов строк, я думаю, вы можете сделать это с помощью scan:

  admission_code = scan(infoTxt, 2, '3A0A0D'x);
  exit_code = scan(infoTxt, 4, '3A0A0D'x);

Используется шестнадцатеричный литерал '3A0A0D'x для указания :, перевода строки и возврата каретки в качестве разделителей для функции scan.

0 голосов
/ 06 сентября 2018

SAS может использовать регулярные выражения Perl через семейство функций, которые начинаются с PRX. Подсказка - отличное резюме, если вы знакомы с регулярными выражениями.

PRXMATCH и PRXPOSN могут протестировать шаблон регулярных выражений с группами захвата и извлечь текст группы.

data have;
input;
text = _infile_;
datalines;
Admission Code: 123456 X Exit Code: 98765W
Admission Code: 4567 WY Exit Code: 76543Z
Admission Code: 67890 L Exit Code: 4321Z
run;

data want;
  set have;

  if _n_ = 1 then do;
    retain rx;
    rx = prxparse ('/Admission Code: (.*)Exit Code:(.*)/');
  end;

  length AdmissionCode ExitCode $50;

  if prxmatch(rx,text) then do;
    AdmissionCode = prxposn(rx, 1, text);
    ExitCode = prxposn(rx, 2, text);
  end;

  drop rx;
run;
0 голосов
/ 06 сентября 2018

Мне нравится RegEX с буфером захвата столько же, сколько следующему, но вы также можете использовать функции оператора ввода для чтения этих данных.

data info;
   infile cards n=2 firstobs=2;
   input #1 patient:$3. location :$1. @'Admission Code: ' AdmissionCode &$16. #2 @'Exit Code: ' ExitCode &$16.;
   cards;
Patient    Location    infoTxt
001        B           Admission Code: 123456 X
                       Exit Code: 98765W
002        C           Admission Code: 4567 WY
                       Exit Code: 76543Z
003        D           Admission Code: 67890 L
                       Exit Code: 4321Z
;;;;
   run;
proc print;
   run;

enter image description here

0 голосов
/ 06 сентября 2018

Там может быть решение, которое делает все это за один шаг данных. Это создает два шага, чтобы справиться с входом и выходом, находящимся в разных строках - сначала шаг данных, затем объединение, чтобы вернуть его обратно.

SAS имеет синтаксис регулярных выражений, но вместо этого я использовал символьные функции SAS. substr имеет 3 аргумента: строку, начальную позицию и конечную позицию, но конечная позиция не обязательна, и я ее опускал, чтобы сказать, что нужно захватить все после начальной позиции. retain используется для заполнения пациента и местоположения во втором ряду каждой группы.

data admission exit;
    set grep;
    retain patient2 location2;
    if patient ne '' then do; 
        patient2=patient;
        location2=location;
        admissioncode=substr(infoTxt,find(infoTxt,":")+2);
        output admission;
        end;
    else do;
        exitcode=substr(infoTxt,find(infoTxt,":")+2);
        output exit;
        end;
run;
proc sql;
    create table dat as select a.patient2 as patient,a.location2 as location,a.admissioncode,b.exitcode
        from admission a
        left join exit b on a.patient2=b.patient2 and a.location2=b.location2
    ;
quit;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...