SAS DO Loop 似乎跳过了记录

SAS DO Loop seems to skip records

在编写一个非常简单的数据步骤来开始一个新项目时,我 运行 遇到了一些 st运行ge 行为。

set1 和 set2 之间的唯一区别是在 set1 的方程式中使用变量 lagscore,而在 set2 的方程式中使用 dummy。

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;`

第 1 组结果

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

关键点是,当您调用 lag() 函数时,它 return 是队列中用缺失值初始化的值。默认是一个队列,里面有一个项目。

在您的代码中:

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) 将 return 缺失。

循环的第二次迭代(obs=3),LAGSCORE会被赋值为500(从队列中读取),并将SCORE的值(缺失值)写入队列。然后根据表达式 lagscore + 1 /(b_dist * lagscore + a_dist).

为分数分配值 500.2

循环的第三次迭代(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 ;

Returns:

 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