SAS DO Loop似乎跳过了记录

时间:2018-12-29 13:20:08

标签: sas datastep

在编写一个非常简单的DATA步骤以启动一个新项目时,我遇到了一些奇怪的行为。

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

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 :(得分: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将存储在队列中。由于缺少LAGSCORE,将为SCORE分配一个缺少的值,因此表达式lagscore + 1 /(b_dist * lagscore + a_dist)将返回缺少的内容。

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

返回:

 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