我有一个像这样的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中做到这一点?
答案 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;