Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 使用do循环创建层次结构_Loops_Sas - Fatal编程技术网

Loops 使用do循环创建层次结构

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;

我试图从两列构建层次结构,其中一列是客户机标识符,另一列是其直接父级,但我有一个问题,因为客户机可以有一个父级,而另一个父级可以有另一个父级

目前,我在一个宏中有许多merge语句

%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;