SAS逻辑根据另一行填充第一行

时间:2020-01-02 18:25:21

标签: 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中做到这一点?

2 个答案:

答案 0 :(得分:1)

Proc DS2程序的上下文中,这是一种基于哈希的方法。

每个节点(名称)只有一个父节点(mgrname),因此散列可以使用名称作为键并以mgrname作为数据。循环查找方法将寻找某个节点的祖先父代或找不到该父节点。

示例(名称为id,名称mgr为pid):

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;

答案 1 :(得分:0)

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

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;