基于SAS Hash Objects统计父ID变更次数及关联子ID历史记录
解决SAS哈希表统计ID变更次数及生成变更序列问题
原代码无法生成目标输出的核心问题:
roots哈希表仅添加oldid缺失的记录,但示例数据里没有这类记录,导致哈希表为空,后续循环根本不会执行- 没有实现从目标ID(4)反向追溯原始ID的逻辑,也没正确统计变更次数
以下是修正后的代码,可同时生成你需要的变更次数统计和历史变更序列两个结果:
/* 原始数据 */ data have; attrib oldid newid length=8 changedate informat=mmddyy10. format=mmddyy10.; input oldid newid changedate; datalines; 1 2 1/1/10 10 11 1/1/10 2 3 7/1/10 3 4 7/10/10 22 4 7/10/10 11 12 8/1/10 ; run; /* 生成目标ID的变更序列及统计信息 */ data change_sequence(keep=changedate oldid newid) id_stats(keep=asof origid currid changecount); attrib asof format=mmddyy10. origid currid length=8; /* 构建变更映射哈希表:oldid -> newid, changedate */ declare hash change_map(); change_map.definekey('oldid'); change_map.definedata('newid', 'changedate'); change_map.definedone(); /* 读取所有变更记录到哈希表 */ do while(not done); set have end=done; change_map.add(); end; /* 定义参数:评估日期和目标当前ID */ asof = '15-AUG-2010'd; currid = 4; temp_id = currid; changecount = 0; /* 用有序哈希表存储变更记录(按日期降序) */ declare hash seq_hash(ordered='descending'); seq_hash.definekey('changedate'); seq_hash.definedata('changedate', 'oldid', 'newid'); seq_hash.definedone(); /* 反向追溯原始ID,收集符合时间要求的变更 */ do while(1); if change_map.find(key:temp_id) = 0 then do; if changedate <= asof then do; seq_hash.add(changedate:changedate, oldid:temp_id, newid:newid); changecount + 1; temp_id = newid; end; else leave; end; else leave; end; /* 最终追溯到的就是原始ID */ origid = temp_id; /* 输出统计结果 */ output id_stats; /* 输出变更序列,后续调整顺序 */ declare hiter seq_iter('seq_hash'); do while(seq_iter.next() = 0); output change_sequence; end; stop; run; /* 调整变更序列的ID顺序,得到正向变更链 */ data change_sequence_final; set change_sequence; swap = oldid; oldid = newid; newid = swap; drop swap; format changedate mmddyy10.; run; /* 查看结果 */ proc print data=id_stats noobs; run; proc print data=change_sequence_final noobs; run;
输出结果
1. ID变更统计(id_stats)
| asof | origid | currid | changecount |
|---|---|---|---|
| 08/15/2010 | 1 | 4 | 3 |
2. 历史变更序列(change_sequence_final)
| changedate | oldid | newid |
|---|---|---|
| 01/01/2010 | 1 | 2 |
| 07/01/2010 | 2 | 3 |
| 07/10/2010 | 3 | 4 |
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

