我有截至今天的ID和ID更改的历史。我想知道ID最近的ID是什么,以及在特定的历史日期与之相关的所有ID;并且还具有ID已经改变的次数的计数。
下面的代码产生";想要"数据集,但它不是随时间而正确的。
data have;
attrib OldID NewID length=8 ChangeDate informat=mmddyy10. format=mmddyy10.;
input OldID NewID ChangeDate;
datalines;
4 . 8/1/10
12 . 8/1/10
11 12 8/1/10
3 4 7/10/10
2 3 7/1/10
1 2 1/1/10
10 11 1/1/10
;
data want(keep=asof origID currID changeCount);
attrib asof format=mmddyy10. origID currID length=8;
declare hash roots();
roots.defineKey('OldID');
roots.defineData('OldID', 'ChangeDate');
roots.defineDone();
declare hash changes();
changes.defineKey('NewID');
changes.defineData('OldID', 'ChangeDate');
changes.defineDone();
do while (not done);
set have end=done;
if missing(NewID) then roots.add();
else changes.add();
end;
array asofs (7) _temporary_ (
'15-MAR-2010'd
'02-JUL-2010'd
'15-JUL-2010'd
'15-AUG-2010'd
);
declare hiter hi('roots');
do index = 1 to dim(asofs);
asof = asofs(index);
do while (hi.next() eq 0);
origID = OldID;
currID = .;
do changeCount = 0 by 1 while (ChangeDate <= asof);
currID = OldID;
if changes.find(key:OldID) ne 0 then leave;
End;
output;
end;
end;
stop;
run;
数据集Want如下所示:
asof | 原始ID | currID | 更改计数||
---|---|---|---|---|
2010年3月15日 | 12 | |||
2010年3月15日 | 4 | 2 | 3 | |
2010年2月7日 | 12 | 11 | 2||
2010年2月7日 | 4 | 3 | 2 | |
2010年7月15日 | 12 | |||
2010年7月15日 | 4 | <1>|||
2010年8月15日 | 12 | 0 | ||
2010年8月15日 | 4 | 0 | ||
12 | 10 | 2 | ||
4 | 1 | 3 | ||
12 | 10 | 2 | ||
4 | 1 | 3 | ||
12 | 10 | 2 | ||
4 | 1 | 3 |
因此,您需要向后思考。这似乎是你想要的,尽管你必须添加一些代码来处理最后2行——8/15日期是在你的最终日期之后的。我想你可以很容易地处理这个问题。
data want(keep=asof origID currID changeCount);
attrib asof format=mmddyy10. origID currID length=8;
declare hash roots();
roots.defineKey('OldID');
roots.defineData('OldID', 'ChangeDate');
roots.defineDone();
declare hash changes();
changes.defineKey('NewID');
changes.defineData('OldID', 'ChangeDate');
changes.defineDone();
do while (not done);
set have end=done;
if missing(NewID) then roots.add();
else changes.add();
end;
array asofs (7) _temporary_ (
'15-MAR-2010'd
'02-JUL-2010'd
'15-JUL-2010'd
'15-AUG-2010'd
);
declare hiter hi('roots');
*add code to deal with asofs dimensions not equal to actual contents;
do index = 1 to dim(asofs) while (asofs[index] ne .);
asof = asofs(index);
do while (hi.next() eq 0);
origID = OldID;
currID = .;
*start at -1 instead of 0 because it always increments 1x too many;
*And, look while changedate is GREATER than, bc you are coming from the larger end;
do changeCount = -1 by 1 while (changeDate > asof);
currID = OldID;
if changes.find(key:OldID) ne 0 then leave;
End;
output;
end;
end;
stop;
run;