假设我有一个在名为的数据集中表示的有向图links,它有两个变量:from_id和to_id.我想使用SAS Data Step做两件事:(1)计算节点数,(2)计算边数.
假设links数据集如下所示.
from_id to_id
----------------
1 2
2 3
3 1
3 2
Run Code Online (Sandbox Code Playgroud)
在此示例中,有3个节点和4个边.(我们可以假设没有重复的边缘中links).节点为1,2和3.边缘为1-> 2,2-> 3,3-> 1和3-> 2.
下面是一个SAS宏,它使用SAS Data Step和proc sql来计算节点和边缘.它工作得很好,但我希望使用SAS Data Step,这样可以(可能)更快地完成对节点和边缘的计数.
/* display number of nodes and edges for graph */
%macro graph_info(links);
data nodes;
set &links;
node_id = from_id;
output;
node_id = to_id;
output;
keep node_id;
run;
proc sql noprint;
select count(distinct node_id) into :numNodes from nodes;
quit;
proc datasets lib=work nolist;
delete nodes;
quit;
proc sql noprint;
select count(*) into :numEdges from &links;
quit;
%put Nodes: &numNodes;
%put Edges: &numEdges;
%mend;
Run Code Online (Sandbox Code Playgroud)
如果您有足够的内存,则可以使用哈希对象执行此操作.
请注意:此代码未经测试,因为我没有安装SAS设备.但是基本的想法应该有效.您遍历数据步骤,将每个节点添加到哈希对象,并在最后一个对象上将宏变量设置为哈希对象的大小.
data _null_;
set links end=lastrec;
format node_id 8.;
if _N_ eq 1 then do;
declare hash h();
h.defineKey("node_id");
h.defineDone();
end;
node_id = from_id;
rc=h.find();
if rc ne 0 then h.add();
node_id = to_id;
rc=h.find();
if rc ne 0 then h.add();
if lastrec then do;
call symput('numLinks', put(h.num_items, 8. -L));
call symput('numEdges', put(_N_, 8. -L));
end;
run;
Run Code Online (Sandbox Code Playgroud)