【问题标题】:SAS: Hidden retain statement inside set statement?SAS:在集合语句中隐藏保留语句?
【发布时间】:2025-12-28 06:55:16
【问题描述】:

考虑以下示例:

/* 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 个观察值,全为 1,数据集编号包含一个变量 (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;

它确实符合我的预期。)

【问题讨论】:

    标签: sas


    【解决方案1】:

    是的,在SETMERGEUPDATE 语句中定义的任何变量都会自动保留(未在数据步骤循环的顶部设置为缺失)。你可以有效地忽略它

    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 替换为缺失。

    【讨论】:

    • 哈,我喜欢关于多对一合并的评论,但我仍然对 set 语句的情况感到困惑。假设您的答案令人困惑的案例变成了简单的案例,但简单的案例现在变得令人困惑。在我帖子的最后一个数据声明中,为什么没有保留变量 A 和 B?它们毕竟是由 set 语句定义的。也许这个问题的简短版本是:如果 set 语句只设置一个数据集怎么办?
    • 它们被保留。但是,它们每次也会被 set 语句中的缺失值替换。我将在编辑中进一步解释。