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
在编写一个非常简单的数据步骤来开始一个新项目时,我 运行 遇到了一些 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)
.
循环的第三次迭代(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