SAS DO Loop, кажется, пропускает записи

При написании очень простого шага DATA, чтобы начать новый проект, я столкнулся с некоторым странным поведением.

Единственное различие между set1 и set2 состоит в использовании переменной lagscore в уравнении в set1 против dummy в уравнении в set2.

set1 производит вывод, который, по-видимому, указывает на то, что включение lagscore приводит к тому, что переменные Score и Lagscore будут неопределенными в половине итераций.

Обратите внимание, что я был осторожен, чтобы НЕ вызывать lag() более одного раза, и я включаю вызов в set2 просто для того, чтобы убедиться, что вызов функции lag() не является источником проблемы.

Я ценю любые объяснения. Я довольно долго отсутствовал в SAS и чувствую, что упускаю что-то фундаментальное в том, как происходит обработка.

(Извините за трудный для чтения вывод. Я не мог понять, как вставить его и сохранить интервал)

data set1;
obs=1;
score=500;
a_dist = -5.0;
b_dist = 0.1;
dummy = 0;
output;
do obs = 2 to 10;
    lagscore = lag(score);
    score = lagscore + 1 /(b_dist * lagscore + a_dist);
    output;
end;
run;
data set2;
obs=1;
score=500;
a_dist = -5.0;
b_dist = 0.1;
dummy = 0;
output;
do obs = 2 to 10;
    lagscore = lag(score);
/*      score = lagscore + 1 /(b_dist * lagscore + a_dist);*/
    score = dummy + 1 /(b_dist * dummy + a_dist);
    output;
end;
run;`

Set1 результаты

obs score   a_dist  b_dist  dummy   lagscore

1   500     -5  0.1 0   .

2   .       -5  0.1 0   .

3   500.02  -5  0.1 0   500

4   .       -5  0.1 0   .

5   500.04  -5  0.1 0   500.02

6   .       -5  0.1 0   .

7   500.06  -5  0.1 0   500.04

8   .       -5  0.1 0   .

9   500.08  -5  0.1 0   500.06

10  .       -5  0.1 0   .

Set2 результаты

obs score   a_dist  b_dist  dummy   lagscore

1   500     -5  0.1 0   .

2   -0.2    -5  0.1 0   .

3   -0.2    -5  0.1 0   500

4   -0.2    -5  0.1 0   -0.2

5   -0.2    -5  0.1 0   -0.2

6   -0.2    -5  0.1 0   -0.2

7   -0.2    -5  0.1 0   -0.2

8   -0.2    -5  0.1 0   -0.2

9   -0.2    -5  0.1 0   -0.2

10  -0.2    -5  0.1 0   -0.2

1 ответ

Решение

Ключевым моментом является то, что когда вы вызываете функцию lag(), она возвращает значение из очереди, которая инициализируется пропущенными значениями. По умолчанию это очередь с одним элементом.

В вашем коде:

score=500 ;
*...;
do obs = 2 to 10;
    lagscore = lag(score);
    score = lagscore + 1 /(b_dist * lagscore + a_dist);
    output;
end;

На первой итерации цикла (obs=2) LAGSCORE будет назначено пропущенное значение, поскольку очередь инициализируется пропущенным значением. Значение 500 будет сохранено в очереди. SCORE будет присвоено пропущенное значение, потому что отсутствует LAGSCORE, и, следовательно, выражение lagscore + 1 /(b_dist * lagscore + a_dist) вернется пропавшим без вести.

На второй итерации цикла (obs=3) LAGSCORE будет присвоено значение 500 (чтение из очереди), а значение SCORE (отсутствующее значение) будет записано в очередь. Затем баллу присваивается значение 500,2 из выражения lagscore + 1 /(b_dist * lagscore + a_dist),

На третьей итерации цикла (obs=4) LAGSCORE будет присвоено пропущенное значение (считанное из очереди), а значение 500.2 будет записано в очередь.

И этот шаблон повторяется.

Если я понимаю ваше намерение, вам на самом деле не нужна функция LAG для такого рода создания данных. Вы можете просто использовать DO Цикл с оператором вывода в нем и обновлять значение SCORE после вывода каждой записи. Что-то вроде:

data set1 ;
  score = 500 ;
  a_dist = -5.0 ;
  b_dist = 0.1 ;
  do obs = 1 to 10 ;
    output ;
    score = score + (1 /(b_dist * score + a_dist)) ;
  end ;
run ;

Возвращает:

 score     a_dist    b_dist    obs

500.000      -5        0.1       1
500.022      -5        0.1       2
500.044      -5        0.1       3
500.067      -5        0.1       4
500.089      -5        0.1       5
500.111      -5        0.1       6
500.133      -5        0.1       7
500.156      -5        0.1       8
500.178      -5        0.1       9
500.200      -5        0.1      10
Другие вопросы по тегам