Loops SAS中嵌套dow循环的说明
我想知道下面的伪代码是如何工作的?如果有一个成功的例子,我将不胜感激Loops SAS中嵌套dow循环的说明,loops,sas,Loops,Sas,我想知道下面的伪代码是如何工作的?如果有一个成功的例子,我将不胜感激 data want; do until (last.var1); do until (last.var2); set have; * other sas statements; end; end; run; 基本上,单个DoW循环允许您在每个变量边界之后执行特定操作,并且与正常数据步骤的计时略有不同(这可能有用,也可能没有)。因此,考虑到这一组: data have; i
data want;
do until (last.var1);
do until (last.var2);
set have;
* other sas statements;
end;
end;
run;
基本上,单个DoW循环允许您在每个变量边界之后执行特定操作,并且与正常数据步骤的计时略有不同(这可能有用,也可能没有)。因此,考虑到这一组:
data have;
input x y z;
datalines;
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
;;;;
run;
以下是正常数据步骤:
data want;
set have;
by x;
if first.x then do;
put "First value of " x=;
end;
put _all_;
if last.x then do;
put "Last value of " x=;
end;
run;
以下是道琼斯指数:
data want_dow;
put "First value of " x=;
do _n_ = 1 by 1 until (last.x);
set have;
by x;
put _all_;
end;
put "Last value of " x=;
run;
请注意,它的结果略有不同-对于第一次迭代和最后一次迭代,它输出不同的行。这是因为SAS在第一种方法中自动为我们做所有这些事情,而DoW loop你必须自己做(例如,如果你想要全部8个,你必须在那里放一个OUTPUT
语句,并且你必须测试EOF和STOP`if true)
但也许这就是你想要的——你希望一开始没有价值,然后你想做点什么。这就是道循环有用的时候
嵌套的DoW循环是相同的,只是可以在两个不同的点上执行操作。请注意,它实际上并没有改变读取行的方式:每次运行到set
语句时,都会从数据集中读取下一行(无论该行是什么)。同样的顺序,只是你有更多的停止点让你写代码
data want;
set have;
by x y;
if first.x then do;
put "First value of " x=;
end;
if first.y then do;
put "First value of " y=;
end;
put _all_;
if last.y then do;
put "Last value of " y=;
end;
if last.x then do;
put "Last value of " x=;
end;
run;
data want_dow;
put "First value of " x=;
do _n_ = 1 by 1 until (last.x);
put "First value of " y=;
do _n_ = 1 by 1 until (last.y);
set have;
by x y;
put _all_;
end;
put "Last value of " y=;
end;
put "Last value of " x=;
run;
同样,这里也存在差异,因为DoW循环“first”在读取第一行之前执行操作,这也可能有帮助,也可能没有帮助,这取决于您的用例。我不认为我曾经有过这样的用例,但这肯定不是不可能的
这里有一个有用的例子,你基本上是手工做一个PROC MEANS
。当然,这两种方法都可以做到;有些人会喜欢每一种
data want_dow;
do _n_ = 1 by 1 until (last.x);
do _n_ = 1 by 1 until (last.y);
set have;
by x y;
z_sum_y = sum(z_sum_y,z);
z_sum_x = sum(z_sum_x,z);
end;
z_sum = z_sum_y;
output;
call missing(z_sum_y);
end;
call missing(y);
z_sum = z_sum_x;
output;
drop z_sum_y z_sum_x;
run;
data want;
set have;
by x y;
z_sum_y+z;
z_sum_x+z;
if last.y then do;
z_sum = z_sum_y;
output;
z_sum_y=0;
end;
if last.x then do;
z_sum = z_sum_x;
call missing(y);
output;
z_sum_x=0;
end;
drop z_sum_y z_sum_x;
run;
不过,DoW循环对Double DoW循环最为有用,DoW循环用于汇总,然后在同一数据步迭代中读取汇总值。这是相同的摘要,但允许您查看当前行上的值。如果您想看到差异,可以将have中的Z值更改为其他值(我有意将它们设置为patterns中的1/2,以便更容易检查)
要在没有双道循环的情况下实现这一点,您必须将第一个want
的结果合并回have
。这不一定是什么大问题,但这是数据的第二次传递;Double DoW循环利用缓冲来避免实际重新执行第二次读入的I/O
data want_ddow;
array z_sum_ys[2] _temporary_;
do _n_ = 1 by 1 until (last.x);
do _n_ = 1 by 1 until (last.y);
set have;
by x y;
z_sum_ys[y] = sum(z_sum_ys[y],z);
z_sum_x = sum(z_sum_x,z);
end;
end;
do _n_ = 1 by 1 until (last.x); *do not need nesting here;
set have;
by x y;
z_sum_y = z_sum_ys[y];
output;
end;
call missing(of z_sum_ys[*] z_sum_x);
run;