SAS DO Loop, кажется, пропускает записи - PullRequest
0 голосов
/ 29 декабря 2018

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

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

set1 создает вывод, который указывает на то, что включение lagscore приводит к тому, что переменные счета и 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 Ответ

0 голосов
/ 29 декабря 2018

Ключевым моментом является то, что когда вы вызываете функцию 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
...