我有一个数据集,如下所示:
child $ parent $
A .
B A
C A
D B
E C
F D
G E
这意味着A是第1代的祖先,B和C是A的孩子,所以第2代,等等
如何计算数据集的生成?
我期望的输出如下:
child $ parent $ generation
A . 1
B A 2
C A 2
D B 3
E C 3
F D 4
G E 4
您只需不断将输出与输入重新连接即可。为此,您需要使用宏逻辑,以便可以重复生成 SAS 代码。
首先让我们将您的列表转换为实际的数据集。
data have;
input child $ parent $ ;
cards;
A .
B A
C A
D B
E C
F D
G E
;
然后我们来定义一个宏。首先,它应该通过查找所有顶级节点(没有父节点的节点)来设置目标数据集。然后它可以循环将子级添加到下一个级别,直到找不到子级。
%macro levels(in=,out=);
%local level nobs;
data &out;
set &in nobs=nobs;
if _n_=1 then call symputx('nobs',nobs);
level=1;
if missing(parent);
run;
proc sql;
%do level=1 %to &nobs ;
create table next as
select a.child,a.parent,&level+1 as level
from &in a
inner join &out(where=(level=&level)) b
on a.parent = b.child
;
%let nobs=&sqlobs;
insert into &out select * from next;
options _last_=&out;
drop table next;
%if &nobs < 1 %then %do;
quit;
%return;
%end;
%end;
quit;
%if &nobs>0 %then %put NOTE: Please check for cycles in your tree.;
%mend levels;
然后您可以调用传入数据集的宏。
%levels(in=have,out=want);
结果:
Obs child parent level
1 A 1
2 B A 2
3 C A 2
4 D B 3
5 E C 3
6 F D 4
7 G E 4