2014-10-15 4 views
1

Я довольно новый с do loops в SAS, и я знаю, что я пытаюсь заставить этот цикл работать как скрипт MATLAB. Я не нашел много полезных советов в Интернете, поскольку большинство примеров do-loop предназначены только для вычислений, а не для проверки того, имеет ли строка перед текущим одно значение.SAS Do-Loop и IF Statement для сравнения значений текущей и предыдущей строк

Вот мой вопрос, что мне нужно решить:

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

Policy 
26X0118907 
26X0375309 
26X0375309 
26X0527509 

Я бы считал i=1 быть первой политики (26X0118907) и i=2 быть второй курс (26X0375309).

В этом случае в соответствии с кодом (который не работает) ниже этого приращения будет помечен как «B». Знаете ли вы, как правильно кодировать такую ​​ситуацию?

data AF_Inforce_&thestate.; 
set AF_Inforce_&thestate.; 
by Rating_St; 

if first.Rating_St then counter=0; 
counter+1; 

myloop: 
do i=2 to counter; 
P2(i)=Policy(i); 
P1(i)=Policy(i-1); 

if P1(i)=P2(i) then flag='A'; 
else flag='B'; 

end; 
return; 

run; 

ответ

3

Первое, что вам нужно узнать, что происходит с MATLAB или аналогичным языком, является то, что SAS отличается. В частности, шаг DATA - это собственный цикл DO, зацикливающий записи.

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

Vasja показал вам один (lag, который фактически не переходит к предыдущей записи, но вроде как действует). dif делает то же самое, кроме сравнения, поэтому, если ваша полинума была числовой, код Ваши можно было бы переписать как dif(policy)=0 вместо policy=lag(policy) (хотя это только для цифр).

Лучший трюк, на мой взгляд, в вашем случае заключается в использовании групповой обработки by. Обычно это работает с отсортированными полями, но здесь не имеет значения, отсортирован ли он: вы просто хотите знать, совпадают ли две последовательные строки, не так ли?

data want; 
    set have; 
    by rating_st policy notsorted; 
    if first.policy and last.policy then recflag='A'; 
    else if first.rating_st then recflag='A'; 
    else recflag='B'; 
run; 

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

2

Попробуйте посмотреть на LAG функции (она «запоминает» значения переменной в очереди)

Ваш код должен идти, как это:

data AF_Inforce_&thestate.; 
set AF_Inforce_&thestate.; 
by Rating_St; 

if first.Rating_St = 0 and Policy=LAG(Policy) then flag='A'; 
else flag='B'; 

run; 
+0

Я бы воздержался от использования функции lag(), за исключением редких случаев, когда вам нужно несколько лаг в одно и то же время. (Например, http://stackoverflow.com/questions/25898255/sas-do-loops-use-loop-variable-inside-the-loop-to-create-lagged-variables). Причина этого заключается в том, что «отставание () 'слишком легко неправильно используется и неправильно понимается, особенно когда присутствует условная логика. Если ваш оператор 'if' был преобразован в вложенные операторы' if', тогда результаты будут изменены без уведомления пользователя. Это может привести к жестким отладкам и необнаруженным ошибкам. Обработка по группам намного безопаснее. –