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_ID1 和 C_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_ID1 和 C_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 方法更快。
寻找使用 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_ID1 和 C_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_ID1 和 C_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 方法更快。