如果在多对多 SAS 合并中没有匹配项,如何将保留值设置为缺失值?

How do you set retained values to missing if there's no match in a many-to-many SAS merge ?

我有两个要合并的数据集,它们按变量重复,但行数不相等。在 SAS 中,默认行为是保留所有不匹配的行的值。

例如:

data a;
    input i x y;
    datalines;
        1 1 5
        1 2 6
        1 3 7
        1 4 8
        ;
run;

data b;
    input i f g $;
    datalines;
        1 9 aa
        1 8 bb
        ;
run;

这里数据集a有四行by变量i,而数据集b只有两行。

仅与变量 i 合并产生:

data c;
    merge a b;
    by i;
run; 

Obs    i    x    y    f    g
1     1    1    5    9    aa
2     1    2    6    8    bb
3     1    3    7    8    bb
4     1    4    8    8    bb

您可以看到,对于 obs 3 和 4 中的变量 fg,值已被保留,因为它们在数据集 a 中没有匹配项。

我想要生成的是这个输出:

Obs    i    x    y    f    g
1     1    1    5    9    aa
2     1    2    6    8    bb
3     1    3    7    .    
4     1    4    8    .    

我正在使用 SAS 9.4,这是我尝试过的:

data c;
    if _n_>1 then do;
        array num{*} _numeric_;
        array char{*} _character_;
        call missing(of num{*});
        call missing(of char{*});
        end;
    merge a b;
    by i;
run;

我的想法是,对于第一行之后的每一行,我都想将所有变量都设置为缺失,这样如果它们没有匹配的行,它们的值就不会被覆盖并保持缺失。这将消除保留值。

在第二行应该创建 PDV 并且所有元数据都应该可用于创建这些数组并将它们设置为缺失,但我收到此错误:

WARNING: Defining an array with zero elements.

关于如何修复此代码或其他可以解决问题的代码有什么建议吗?

您可能希望覆盖 run 语句的默认行为,即某些变量的自动输出和自动调用缺失。

在这里你 output; 强制自动输出(与默认行为相同),然后 call missing(of _all_); 将所有变量设置为缺失(而不是仅在 mergeset 语句)。

data c;
    merge a b;
    by i;
    output;
    call missing(of _all_);
run; 

你必须在最后而不是开始时这样做的原因是你在开始时还没有定义任何变量 - 所以 _numeric__character__all_ 没有任何参考。

您可以使用 if 0 then set a b; 解决此问题,但我发现上述解决方案更直接一些。确实两者都可以正常工作并且具有相同的速度和优势。

data c;
    if 0 then set a b; *defines all of the variables, but `if 0` means it will not pull any data;
    call missing(of _all_); *sets everything missing;
    merge a b;
    by i;
run;