PROC SQL - 计算变量的不同值

PROC SQL - Counting distinct values across variables

寻找使用 PROC SQL 计算跨多个列/变量的不同条目的方法,我遇到的只是如何计算值的 组合 。 但是,我想搜索 2 个(字符)列(在满足特定条件的行内)并计算出现在 any 中的不同值的数量。

考虑一个如下所示的数据集:

DATA have;
INPUT       A_ID    C   C_ID1 $ C_ID2 $;
DATALINES;
            1       1   abc         .
            2       0   .           .
            3       1   efg         abc
            4       0   .           .
            5       1   abc         kli
            6       1   hij         .
;
RUN;

我现在想要一个包含 nr 计数的 table。 C_ID1C_ID2 中的唯一值的行,其中 C = 1. 结果应该是 4 (abc, efg, hij, kli):

nr_distinct_C_IDs
4

到目前为止,我只能处理一列 (C_ID1):

PROC SQL;
    CREATE TABLE try AS
          SELECT 
        COUNT (DISTINCT 
            (CASE WHEN C=1 THEN C_ID1 ELSE ' ' END)) AS nr_distinct_C_IDs
                FROM have;
QUIT;

(请注意,我使用 CASE 处理而不是 WHERE 子句,因为我的实际 PROC SQL 也在同一查询中处理其他情况)。

这给了我:

nr_distinct_C_IDs
3

如何将其扩展到两个变量(在我的示例中为 C_ID1C_ID2)?

很难用您的方法将其扩展到两个或更多变量。尝试先堆叠变量,然后计算不同的值。像这样:

proc sql;
   create table want as
   select count(ID) as nr_distinct_C_IDs from
       (select C_ID1 as ID from have
       union 
       select C_ID2 as ID from have)
    where not missing(ID);
quit;

我认为在这种情况下,如果您的首要任务是想出可以轻松扩展到大量变量的东西,那么数据步骤可能更合适。例如

data _null_;
    length ID ;
    declare hash h();
    rc = h.definekey('ID');
    rc = h.definedone();
    array IDs $ C_ID1-C_ID2;
    do until(eof);
        set have(where = (C = 1)) end = eof;
        do i = 1 to dim(IDs);
            if not(missing(IDs[i])) then do;
                ID = IDs[i];
                rc = h.add();
                if rc = 0 then COUNT + 1;   
            end;
        end;
    end;
    put "Total distinct values found: " COUNT;
run;

这里需要做的就是将它添加到数组中以容纳更多变量。

N.B。因为它使用哈希对象,所以您将需要足够的内存来保存您希望找到的所有不同值。另一方面,它只读取输入数据集一次,不需要排序,因此它可能比需要多次内部读取和排序的 SQL 方法更快。