SAS сравнения строк и запросов? или другое решение, необходимое. Я в тупике - PullRequest
0 голосов
/ 11 мая 2009

У меня есть ситуация, когда для каждого уникального наблюдения casenum я хотел бы выполнить разные запросы и арифметические операции между различными наблюдениями «кода» для этого «casenum» (см. Ниже). Например, для casenum 1234567 я хотел бы вычесть данные для кода 0200 - код 0234 или 531 - 53. Пожалуйста, имейте в виду, что в этом наборе данных тысячи наблюдений. Есть ли простой способ сделать это или сделать сравнение строк с конкретным.

Обратите внимание, что casenum и code являются символьными переменными, а data - числовой переменной

Вот пример того, как структурирован набор данных:

casenum  code  data

1234567  0123  4597  
1234567  0234    53  
1234567  0100   789  
1234567  0200   531  
1234567  0300   354  
1111112  0123    79  
1111112  0234    78  
1111112  0100    77   
1111112  0200  7954  
1111112  0300    35

Вот логика, хотя, вероятно, синтаксически неверна в том, что я пытаюсь сделать.

Для наблюдений кода, где casenum одинаков, в этих casenum
Я хотел бы определить, если данные для кода 0234 + данные для кода 0100 - данные для кода 0123 ne данные для кода 0200 затем newvariable = 'YES'

Другими словами, я хотел бы, чтобы он проверил, если 53 + 789 - 4597, не 531. После этого и других подобных тестов запускается внутри casenum 1234567, я бы хотел, чтобы он перешел на следующий casenum и запустил те же тесты для этого casenum.

Имейте в виду, что в этом наборе данных содержатся сотни тысяч наблюдений.

Ответы [ 3 ]

1 голос
/ 12 мая 2009

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

/* Transpose the data by casenum */    
proc transpose data=so846572 out=transpose_ds;
    id  code;
    var data;
    by casenum;
run;

/* Now just explicitly write your conditional expression */  
data StackOverflow;
    set transpose_ds;

    if _0234 + _0100 - _0123 <> _0200 then newvariable="yes";
run;

Где so846572 = Ваш исходный набор данных, transpose_ds = Транспонированная версия, StackOverflow = конечный вывод.

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

1 голос
/ 11 мая 2009

Мне неясно, какова ваша логика для вычитаемой части кода, но для выбора группы строк я могу предложить. На первый взгляд, я получил бы список различных значений для casenum.

proc sql;
select distinct casenum 
into :casenum_list separated by ' '
from dataset;
quit;

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

Возможно, с помощью другого процесса sql, как:

%MACRO DOIT;
%LET COUNT=1;
%DO %UNTIL (%SCAN(&casenum_list,&COUNT) EQ);

%LET CASENUM_VAR=%SCAN(&casenum_list,&COUNT);

PROC SQL;
SELECT
<INSERT SOME SQL LOGIC HERE>
FROM 
DATASET
WHERE CASENUM=&CASENUM_VAR;
QUIT;

%LET COUNT=%EVAL(&COUNT+1);        

%MEND DOIT;

%DOIT;

Надеюсь, это поможет. Если вы сможете лучше понять, что вы пытаетесь выполнить в строках, я могу быть более конкретным.

0 голосов
/ 11 мая 2009

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

Data work.temp ;
 retain casenum_data ;

 set lib.data ;
 by casenum ;

 if first.casenum then do ;
   /* <reset hold vars> */
   casenum_data = 0 ;
 end ;

 if code = "0200" or code = "234" then .....


 if last.casenum then do ;
   /* output casenum summary */
   output ;
 end ;

run ;

Опубликуйте больше информации о необходимости и получите дополнительную помощь.

...