我在多个数据集中有一个公共列ID
。现在,我正在寻找在这些数据集中出现多少次ID
。即使ID
在一个数据集中多次出现,数据集中的visit
仍会计为1
。
对于任何m
,ID
数据集给定visit
,值1
介于m
和ID # Visit
222 5
233 5
556 3
...
...
667 1
之间。
理想输出:
222
数据集:(它们没有相同的前缀,这是一个例子)。
data1 :( ID col2 col3 ...
21
222
222
的#访问次数为1,即使出现两次)
222
...
data5 :( ID col87 col12 ...
222
623
126
的#访问次数为1)
tau:
A | B | C
----------
2 - 1 - 12351
3 - 1 - 65462
4 - 1 - 13461
6 - 5 - 12351
7 - 5 - 12351
8 - 5 - 62372
9 - 10 -12351
我不知道如何从这开始。它看起来像是一本字典遍历。
答案 0 :(得分:4)
这没有经过测试,但沿线应该有效:
/*Stack up all of your tables, keep 'ID' only*/
data have (keep=ID);
set data: indsname=dsn;
dsname = dsn;
run;
/*Proc SQL to get the job done*/
Proc sql;
create table want as
select ID, count(distinct dsname) as visit from have
group by ID
;
quit;
答案 1 :(得分:0)
这是一个数据步骤方法,假设所有数据集都按ID排序。
基本上,您将当前行的indsname
值与前一行进行比较,如果更改,则将计数增加1.注意与重置计数的方法略有不同 - 我在之后执行 em> indsname检查,并且为1,之前不为0;那是因为在某些情况下,您可能有两个具有不同indsname值的连续ID。由于我们不能在BY语句中使用INDSNAME,因此我们不能依赖SAS来“改变”我们的值(就像我们使用嵌套的语句一样)所以我们必须不按顺序执行。
data data1;
do id = 1 to 20;
output;
end;
run;
data data2;
do id = 1 to 30 by 2;
output;
end;
run;
data data3;
do id = 1 to 30 by 3;
output;
end;
run;
data want;
set data: indsname=dsn;
by id;
count+ifn(dsn=lag(dsn),0,1);
if first.id then count=1;
if last.id then output;
run;
答案 2 :(得分:0)
我认为以下解决方案会起作用(您必须提供要在其上计算统计信息的数据集的列表):
%macro macro_answer(dataset_list);
%let ndsets = %sysfunc(countw(&dataset_list., ' '));
/* Create a frequency table for every dataset in the list of input datasets, containing a column with the dataset name */
/* and the count of each ID in this dataset */
%do i = 1 %to &ndsets;
proc sql;
create table __freq_&i. as
select "%scan(&dataset_list., ' ')" as dataset_name
,ID
,count(*) as _count_
from %scan(&dataset_list., ' ')
group by 1,2
;quit;
%end;
/* Append every frequency table create above */
data __all_datasets_freq;
length dataset_name $41.; /*8 for libname + 1 for '.' + 32 for dataset name*/
set
%do i = 1 %to &ndsets;
__freq_&i.;
%end;
run;
/* Drop intermediary tables for frequency of each dataset */
proc sql;
%do i = 1 %to &ndsets.;
drop table __freq_&i.;
%end;
;quit;
%mend macro_answer;
Haikuo Bian提供的解决方案可能有效,并且也更易于理解,但以我的经验,您应该始终对数据集计算统计信息,然后堆叠所有表,而不是堆叠所有表并计算统计信息。大桌子根据您的计算机和表的大小,使用前者可以提高性能。
此外,如果您的表位于数据库(Teradata,Oracle等)上,并且您正在使用SAS Pass-Through,则无需使用即可通过最有效的方式使用数据库Pass-Through SAS在计算统计信息之前附加所有表并在大表上创建。除此之外,对我的代码进行少量调整,您就可以使用字典表 dictionary.tables 在具有特定模式名称的数据集上遍历整个lib(甚至在lib列表上)。
免责声明:我现在无法访问SAS,因此无法确认我提供的代码是否确实有效。