Loops 使用do循环创建层次结构
我试图从两列构建层次结构,其中一列是客户机标识符,另一列是其直接父级,但我有一个问题,因为客户机可以有一个父级,而另一个父级可以有另一个父级 目前,我在一个宏中有许多merge语句Loops 使用do循环创建层次结构,loops,sas,Loops,Sas,我试图从两列构建层次结构,其中一列是客户机标识符,另一列是其直接父级,但我有一个问题,因为客户机可以有一个父级,而另一个父级可以有另一个父级 目前,我在一个宏中有许多merge语句 %macro hierarchy (level); data sourcedata (drop = PARENT_ID); merge sourcedata (in = a) inputdata (in = b); by CLIENT_ID;
%macro hierarchy (level);
data sourcedata (drop = PARENT_ID);
merge sourcedata (in = a)
inputdata (in = b);
by CLIENT_ID;
if a;
length Parent_L&level $32.;
Parent_L&level = PARENT_ID;
if Parent_L&level = Parent_L%eval(&level-1) then Parent_L&level ="";
CLIENT_ID = Parent_L&level;
proc sort;
by Parent_L&level;
run;
%mend;
%hierarchy(2)
%hierarchy(3)
%hierarchy(4)
我的输出看起来像
client_ID Parent_L1 Parent_L2 Parent_L3 Parent_L4
clientA clientB . . .
ClientE clientA clientB . .
我在寻找一种方法,直到最后一个父项都为空,因为我不确定我需要达到多少级别
谢谢你需要的长度是树的深度。 在SQL中计算它有点麻烦,因为您确实需要一个哈希表,或者至少是数组。 您可以使用从子级访问父级。 如果您有SAS/OR,则更容易: 您可以解a并从中生成表 从森林的根部开始的小路。 在本例中,我将使用以下数据集:
数据已经存在;
填充数据线分隔符=“|”;
输入主题1主题2;
数据线;
2 | 4
2 | 5
2 | 6
2 | 8
4 | 7
4 | 11
6 | 9
6 | 10
6 | 12
10 | 15
10 | 16
13 | 14
16 | 17
;
proc optmodel printlevel=0;
设立转介;
set CLIENTS=union{in references}{u,v};
set ROOTS=CLIENTS diff setof{in REFERRALS}v;
已将数据读入引用=[subject1 subject2];
/*源、汇、序列、尾、头*/
设置路径;
num len{root,CLIENTS}init。;
num longest=最大值(长度[*]);
使用网络/图形求解\u方向=定向
链接=(包括=转介)
out=(sppaths=路径spweights=len)
短路径=(源=根)
;
num parent{ci在客户端中,i在1..longest}init中。;
对于{in path}
父[v,len[u,v]-i+1]=s;
打印父对象;
从[client]=客户端创建所需数据
{i in 1..longest};
退出
您有SAS/OR吗?如果是这样的话,请查看PROC BOM。此链接可能会有所帮助,有很多方法可以在不使用宏的情况下执行此操作。@Reeza提供的线程非常方便。稍后的响应还显示了一种处理树结构的方法:。您可以将5 18 19 18 20
添加到卡中
,查看它如何将其解析到子网1中。
data have;
infile datalines delimiter='|';
input subject1 subject2;
datalines;
2 | 4
2 | 5
2 | 6
2 | 8
4 | 7
4 | 11
6 | 9
6 | 10
6 | 12
10 | 15
10 | 16
13 | 14
16 | 17
;
proc optmodel printlevel=0;
set<num,num> REFERRALS;
set CLIENTS = union{<u,v> in REFERRALS} {u, v};
set ROOTS = CLIENTS diff setof{<u,v> in REFERRALS} v;
read data have into REFERRALS=[subject1 subject2];
/* source, sink, seq, tail, head. */
set<num,num,num,num,num> PATHS;
num len{ROOTS,CLIENTS} init .;
num longest = max(of len[*]);
solve with NETWORK / graph_direction = directed
links = ( include = REFERRALS )
out = ( sppaths = PATHS spweights = len )
shortpath = ( source = ROOTS )
;
num parent{ci in CLIENTS, i in 1 .. longest} init .;
for{<u, v, i, s, t> in PATHS}
parent[v, len[u,v] - i + 1] = s;
print parent;
create data want from [client]=CLIENTS
{i in 1 .. longest} <COL('Parent_L'||i) = parent[client,i]>;
quit;