考虑以下示例:
/* 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;
因此,数据集包含一个具有3个观察值的变量A,所有数据集和数据集编号包含一个变量(B),其中包含5个观察值:数字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;
它确实做了我期望的事。)
答案 0 :(得分:7)
是的,SET
,MERGE
或UPDATE
语句中定义的任何变量都会自动保留(在数据步骤循环的顶部不会丢失)。您可以使用
output;
call missing(of <list of variables to clear out>);
run;
在数据步骤结束时。
这就是MERGE
适用于多对一合并的方式,顺便说一下,以及多对多合并通常不会按照您希望的方式工作的原因。
“在一起”和“分离”情况之间的区别在于,在单独的情况下,您有两个具有不同变量的数据集。如果以交互模式运行,即SAS程序编辑器或增强编辑器(非EG或批处理模式),则可以使用数据步调试器更清楚地看到这一点。你会看到以下内容:
在ones
数据集的最后一行的末尾:
i A B
3 1 .
通知B存在但缺失。然后它回到数据步骤循环的顶部。所有三个变量都是独立的,因为它们都来自数据集。然后它再次尝试从ones
读取,生成:
i A B
. . .
然后它意识到它无法从ones
读取,并开始从numbers
读取。在numbers
数据集的第一行末尾:
i A B
. . 1
然后它到达顶部,再没有任何改变;然后它为B读取2。
i A B
. . 2
然后根据你的程序将A设置为2:
i A B
. 2 2
然后它再次返回数据步骤循环的开始。
i A B
. 2 2
然后它读入B = 3:
i A B
. 2 3
然后继续循环,B = 4,5。
现在,将其与单个数据集进行比较。它将几乎相同(数据集之间切换的差异很小,不会产生不同的结果)。现在我们进入A = 2 B = 2的步骤:
i A B
. 2 2
现在,当数据步骤读入下一行时,它上面有所有三个变量。所以它产生了:
i A B
. . 3
因为它读入A =。从行开始,它将其设置为缺失。在单数据步骤版本中,它没有A读取的值,因此它没有替换2缺失。