SAS:隐藏的保留语句在set语句中?

Vin*_*ent 6 sas

请考虑以下示例:

/* Create two not too interesting datasets: */
Data ones (keep = A);
Do i = 1 to 3;
A = 1;
output;
End;
run;

Data numbers;
Do B = 1 to 5;
output;
End;
Run;

/* The interesting step: */
Data together;
Set ones numbers;
if B = 2 then A = 2;
run;
Run Code Online (Sandbox Code Playgroud)

因此,数据集包含一个带有3个观测值的变量A,所有数据集和数据集编号包含一个带有5个观测值的变量(B):数字1到5.我希望结果数据集一起有两列(A和B)和A要读取的列(垂直)1,1,1,.... ,2 ,. ,.,.

但是,在执行代码时,我发现列A读取1,1,1,.... ,2,2,2,2

显然,在第五次观察中创建的2被完全保留下来,没有明显的原因.这里发生了什么?

(为了完整起见:当我将最后一个数据步骤拆分为两个时,如下所示:

Data together;
set ones numbers;
run;
Data together;
set together;
if B = 2 then A = 2;
run;
Run Code Online (Sandbox Code Playgroud)

它确实做到了我的期望.)

Joe*_*Joe 7

是的,这是在所定义的任何变量SET,MERGEUPDATE语句自动保留(未设置在数据步骤循环的顶部丢失).你可以有效地忽略它

output;
call missing(of <list of variables to clear out>);
run;
Run Code Online (Sandbox Code Playgroud)

在数据步骤结束时.

MERGE顺便提一下,这就是多对一合并的工作方式,以及多对多合并通常不会按照您希望的方式工作的原因.


"在一起"和"分离"情况之间的区别在于,在单独的情况下,您有两个具有不同变量的数据集.如果以交互模式运行,即SAS程序编辑器或增强编辑器(非EG或批处理模式),则可以使用数据步调试器更清楚地看到这一点.你会看到以下内容:

ones数据集的最后一行的末尾:

i A B
3 1 .
Run Code Online (Sandbox Code Playgroud)

注意B存在但缺失.然后它回到数据步骤循环的顶部.所有三个变量都是独立的,因为它们都来自数据集.然后它尝试再读ones一次,这会产生:

i A B
. . .
Run Code Online (Sandbox Code Playgroud)

然后它意识到它无法读取ones,并开始从中读取numbers.在numbers数据集的第一行的末尾:

i A B
. . 1
Run Code Online (Sandbox Code Playgroud)

然后它到顶部,再没有任何改变; 然后它读取2为B.

i A B
. . 2
Run Code Online (Sandbox Code Playgroud)

然后根据您的程序将A设置为2:

i A B
. 2 2
Run Code Online (Sandbox Code Playgroud)

然后它再次返回数据步骤循环的开始.

i A B
. 2 2
Run Code Online (Sandbox Code Playgroud)

然后它读入B = 3:

i A B
. 2 3
Run Code Online (Sandbox Code Playgroud)

然后它继续循环,B = 4,5.

现在,将其与单个数据集进行比较.它将几乎相同(数据集之间切换的差异很小,不会产生不同的结果).现在我们进入A = 2 B = 2的步骤:

i A B
. 2 2
Run Code Online (Sandbox Code Playgroud)

现在,当数据步骤读入下一行时,它上面有所有三个变量.所以它产生:

i A B
. . 3
Run Code Online (Sandbox Code Playgroud)

因为它读入A =.从行开始,它将其设置为缺失.在单数据步骤版本中,它没有A读取的值,因此它没有替换2缺失.