基于另一行填充1行的SAS逻辑

基于另一行填充1行的SAS逻辑,sas,Sas,我有这样一个SAS数据集: Name MgrName Dept. A B B C C D X Y 我需要用递归逻辑填写部门。我知道D是“工资单”的负责人,所以我填写: Name MgrName Dept. A B B C C D Payroll X Y 但使用某种递归,D报告链中的每个人(A、B、C)也需要分配“工资单”。在SAS中如何做到这一点?可能有一种更聪明的方法,但这里有一种哈希对象方法 data hav

我有这样一个SAS数据集:

Name MgrName Dept.

A     B
B     C
C     D
X     Y
我需要用递归逻辑填写部门。我知道D是“工资单”的负责人,所以我填写:

Name MgrName Dept.

A     B
B     C
C     D       Payroll
X     Y

但使用某种递归,D报告链中的每个人(A、B、C)也需要分配“工资单”。在SAS中如何做到这一点?

可能有一种更聪明的方法,但这里有一种哈希对象方法

data have;
input Name $ MgrName $;
datalines;
A B
B C
C D
X Y
;

data want(drop=rc);
   declare hash h1(dataset:'have');
   h1.definekey('MgrName');
   h1.definedata('Name');
   h1.definedone();
   declare hash h2();
   h2.definekey('Name');
   h2.definedone();

   length Name $ 100 MgrName $ 100;

   do rc=h1.find(key:'D') by 0 while (rc=0);
      h2.replace();
      rc=h1.find(key:Name);
   end;

   do until (lr);
      set have end=lr;
      Dept=ifc(h2.check()=0, 'Payroll', '');
      output;
   end;
run;

以下是在
Proc DS2
程序上下文中基于哈希的方法

每个节点(名称)只有一个父节点(mgrname),因此哈希可以使用name键并将mgrname作为数据。循环查找方法将查找节点的祖先父级,或者不查找

示例(名称为
id
,名称管理器为
pid
):

数据已经存在;
输入id$pid$;数据线;
A B
B C
C D
fd
G F
氢氟酸
P H
Q H
R H
xy
跑
程序ds2;
数据需要/覆盖=是;
声明包哈希链接();
声明char\u seek\u pid;
声明char\u seek\u id;
申报部门;
保持部门id;
*填充散列;
方法init();
links.definekey('id');
链接。定义数据(“pid”);
dataset(“{select pid,id from have{options locktable=share}”);
links.multidata(“是”);
links.definedone();
结束;
*寻找应用价值的祖先;
方法apply(charrootid、char值、charid);
声明整数限制;
极限=0;
_seek_id=id;
暂且(
links.find([[u seek\u id],[u seek\u pid])=0和
限值<100和
rootid ne\u seek\u pid
);
上限+1;
_seek\u id=\u seek\u pid;
结束;
如果rootid=\u seek\u pid,则dept=value;
结束;
*将某些值应用于某些节点及其子节点;
方法run();
设置有(锁台=共享);
应用('D','payroll',id);
应用('F','shadow$',id);
结束;
enddata;
跑
退出
%让syslast=want;

您的数据是否可以有多个MgrName='D'值?谢谢。不,数据是这样的,“Name”和“MgrName”都是唯一的。名称是否有多个管理器?这种情况应该很少见,但在某些组织中可能会发生。经理可以有多个直接下属吗?这将是正常的,否则您将有N-1个管理者来管理N名员工。请注意,您的名称->管理者名称对基本上是在定义一个图。这里是关于如何找到连通子图的前一个问题。
data have;
input id $ pid $;datalines;
A     B
B     C
C     D
F     D
G     F
H     F
P     H
Q     H
R     H
X     Y
run;

proc ds2;
  data want / overwrite=yes;
    declare package hash links();

    declare char _seek_pid;
    declare char _seek_id;
    declare char dept;

    keep id pid dept;

    * populate hash;
    method init();
      links.definekey('id');
      links.definedata('pid');
      links.dataset('{select pid, id from have {options locktable=share}}');
      links.multidata('yes');
      links.definedone();
    end;

    * seek ancestor from which value should be applied;
    method apply(char rootid, char value, char id);
      declare int limit;

      limit = 0;

      _seek_id = id;

      do while (
         links.find([_seek_id], [_seek_pid]) = 0 and 
         limit < 100 and 
         rootid ne _seek_pid
      );
        limit+1;
        _seek_id = _seek_pid;
      end;

      if rootid = _seek_pid then dept = value;
    end;

    * apply some values to some nodes and children thereof;    
    method run();
      set have (locktable=share);
      apply ('D','payroll', id);
      apply ('F','shadow$', id);
    end;
  enddata;
  run;
quit;

%let syslast = want;