6

考虑以下示例:

/* 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;

因此,数据集包含一个变量 A 和 3 个观察值,所有变量和数据集编号包含一个变量 (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;

它确实符合我的预期。)

4

1 回答 1

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。

于 2013-10-14T14:37:25.530 回答