Функция SAS Scan не работает должным образом - PullRequest
1 голос
/ 04 июля 2019

Я столкнулся с проблемой с функцией сканирования в sas.

У моего набора данных есть одна переменная, которую нужно разделить на несколько переменных.

Переменная имеет следующую структуру:

4__J04__1__SCH175__BE__compositeur /rangeur__compositeur / bewerker __ (пробел) __ 1__17__108.03__93.7

Я использую этот код, чтобы разделить его на несколько переменных:

data /*ULB.*/work.smart_BCSS_withNISS_&JJ.&K.;
                set work.smart_BCSS_withNISS_&JJ.&K.;
                /* Maand splitsen in variablen */
                mois=scan(smart,1,"__");
                jours=scan(smart,2,"__");
                nbjours=scan(smart,3,"__");
                refClient=scan(smart,4,"__");
                paysPrestation=scan(smart,5,"__");
                wordingFR=scan(smart,6,"__");
                wordingNL=scan(smart,7,"__");
                fonction=scan(smart,8,"__");
                ARTISTIQUE2=scan(smart,9,"__");
                Art_At_LEAST=scan(smart,10,"__");
                totalBrut=scan(smart,11,"__");
                totalImposable=scan(smart,12,"__");
run;

В большинстве случаев это работает отлично. Однако иногда 4-я переменная 'refClient' содержит одно подчеркивание, подобное этому:

4__J04__1__LE_46__BE__compositeur /rangeur__compositeur / bewerker __ (пробел) __ 1__17__108.03__93.7

Каким-то образом функция сканирования также обнаруживает это единственное подчеркивание как разделитель, даже если разделитель является двойным подчеркиванием.

Есть идеи, как избежать этого поведения?

Ответы [ 3 ]

4 голосов
/ 04 июля 2019

Код Ауриэли работает, но их ответ не объясняет почему.Ваше понимание того, как работает scan, неверно.

  1. Если в разделителе, указанном для scan, содержится более 1 символа, каждый символ рассматривается как разделитель.Вы указали _ дважды.Если бы вы указали ab, то a и b оба были бы обработаны как разделители, а не ab, являющийся разделителем.
  2. scan по умолчанию обрабатывает несколько последовательных разделителей как одинразделитель, поэтому ваш код рассматривал и __, и _ как разделители.Поэтому, если вы указали ab в качестве строки-разделителя, то ba, abba и т. Д. Также будут по умолчанию считаться как один разделитель.
2 голосов
/ 04 июля 2019

Вы можете использовать regexp, чтобы заменить один '_' (например, изменить на '-'), а затем отсканировать то, что вы хотите:

data /*ULB.*/work.test;
                smart="4__J04__1__LE_18__BE__compositeur / arrangeur__compositeur / bewerker__(blank)__1__17__108.03__93.7";
                smartcr=prxchange("s/(?<=[^_])(_{1})(?=[^_])/-/",-1,smart);
                /* Maand splitsen in variablen */
                mois=scan(smartcr,1,"__");
                jours=scan(smartcr,2,"__");
                nbjours=scan(smartcr,3,"__");
                refClient=tranwrd(scan(smartcr,4,"__"),'-','_');
                paysPrestation=scan(smartcr,5,"__");
                wordingFR=scan(smartcr,6,"__");
                wordingNL=scan(smartcr,7,"__");
                fonction=scan(smartcr,8,"__");
                ARTISTIQUE2=scan(smartcr,9,"__");
                Art_At_LEAST=scan(smartcr,10,"__");
                totalBrut=scan(smartcr,11,"__");
                totalImposable=scan(smartcr,12,"__");
run;
1 голос
/ 05 июля 2019

Интересно, что оператор INFILE поддерживает строку-разделитель enter image description here.

data test;
   infile cards dlmstr='__';
   input (mois
      jours
      nbjours
      refClient
      paysPrestation
      wordingFR
      wordingNL
      fonction
      ARTISTIQUE2
      Art_At_LEAST
      totalBrut
      totalImposable) (:$32.);
   cards;
4__J04__1__SCH175__BE__compositeur / arrangeur__compositeur / bewerker__(blank)__1__17__108.03__93.7
4__J04__1__LE_46__BE__compositeur / arrangeur__compositeur / bewerker__(blank)__1__17__108.03__93.7
;;;;
   run;
proc print;
   run;

enter image description here

...