如何在 SAS 的 DO 循环中使用 SET 语句?

How to work SET statement in a DO loop in SAS?

我研究了 SAS 中 Do 循环中的 SET 语句,但我不明白如何在 DO 循环中使用 SET 语句。

我创建了以下示例数据集 a1:

/* Create data a1 */

data a1 ; 
input fruit $ ; 
cards ; 
melon
apple
orange 
;
run ;

proc print data=a1 ; 
title "Results of a1" ; 
run;

然后,我创建以下新数据集 c1:

/* Create data c1 using a1 -- This is a upper code block */

data c1 ;
do i = 1 to 3 ; 
    set a1 ; 
    count + 1 ;
    N_VAR = _N_ ; 
    ERR_VAR = _ERROR_ ;
    output ; 
end;
run ;

proc print data=c1 LABEL ; 
LABEL N_VAR = "_N_" ; 
LABEL ERR_VAR = "_ERROR_" ; 
title "Results of c1" ; 
run ; 

问题:为什么上面的代码块与下面的代码块没有相同的输出?我不明白如何在 DO 循环中使用 SET 语句。我缺少什么概念?

/* My expectation for c1 -- This is a below code block */

data my_expectation ; 
input i fruit $ count N  ERROR ;
cards ; 
1 melon 1 1 0
1 apple 2 2 0
1 orange 3 3 0
2 melon 4 1 0
2 apple 5 2 0
2 orange 6 3 0
3 melon 7 1 0 
3 apple 8 2 0
3 orange 9 3 0
;
run; 

proc print data=my_expectation label ;
LABEL N = "_N_" ; 
LABEL ERROR = "_ERROR_" ; 
title "The result that I expected for c1" ; 
run ;  

我在下面附上了结果图像文件。

感谢您的关注。

每个SET语句建立一个独立的阅读流。

DATA 步是一个隐式循环。

DO循环迭代3次隐式DATA步循环后returns控制到步的顶部。

在第二次隐式迭代时,进入 DO 循环,在其第一次迭代中到达 SET 语句(第 4 次)。输入数据集 (A1) 没有更多的观测值,因此 DATA 步骤结束。

您可以使用此版本的 DATA 步观察流程行为:

data c1 ;
  put 'TOP';

do i = 1 to 3 ; 

put i= 'pre SET';

    set a1 ; 

put i= 'post SET';

    count + 1 ;
    N_VAR = _N_ ; 
    ERR_VAR = _ERROR_ ;
    output ; 
end;

  put 'BOTTOM';
run;

旁白:

当DATA步没有任何明确的OUTPUT语句时,当控制到达步的底部时,该步将隐式输出一个观察——有一些语句阻止流到达底部,例如,RETURN 语句或子集 IF 语句失败。

我回答了您的 为什么 问题,@Tom 向您展示了 如何 通过数据步骤产生预期结果。结果是 SQL 也可以执行的交叉连接:

data a1 ; 
input fruit $ ; 
cards ; 
melon
apple
orange 
;

data replicates;
  do i = 1 to 3;
    output;
  end;
run;

proc sql;
  create table want as
  select i, a1.*
  from replicates cross join a1
  ;
quit;

如果你想输出每个观察值三次,然后在 SET 之后移动 DO 循环。

set a1;
do i=1 to 3; output; end;

如果你真的想读三遍数据集,那么你要么需要三个单独的 SET 语句

i=1;
set a1;
output;
i=2;
set a1;
output;
i=3;
set a1;
output;

或使用 POINT= 选项明确控制您正在使用 SET 语句读取的观察结果。

do i=1 to 3 ;
  do p=1 to nobs;
    set a1 point=p nobs=nobs ;
    output;
  end;
end;
stop;

大多数 DATA 步在读取输入时停止,由于 POINT= 选项不会发生这种情况,因此您需要 STOP 语句来防止数据步永远重复。