这是计算2的程序,修改一下变量名应该是可以通用的。
如果有什么不明白可以参考我上传的资料:
https://bbs.pinggu.org/thread-1062169-1-1.html。
data sample1;
input co$ 1. date1 yymmdd11. date2 yymmdd11. pa pb;
cards;
A 2001-03-01 2001-03-30 100 150
A 2001-03-06 2001-03-30 100 120
A 2001-03-29 2001-03-30 100 90
A 2001-04-01 2001-04-30 200 160
A 2001-04-15 2001-04-30 200 180
A 2001-04-20 2001-04-30 200 190
A 2001-04-28 2001-04-30 200 180
B 2001-03-01 2001-03-30 105 112
B 2001-03-08 2001-03-30 105 110
B 2001-03-28 2001-03-30 105 60
B 2001-04-05 2001-04-30 100 90
B 2001-04-16 2001-04-30 100 80
B 2001-04-27 2001-04-30 100 105
B 2001-04-28 2001-04-30 100 110
B 2001-04-29 2001-04-30 100 110
;
run;
data _null_;
if _n_=1 then do;
declare hash h2(hashexp:16);
h2.definekey('co','date2');
h2.definedata('co','date2');
h2.definedone();
end;
do until(last);
set sample1 end=last;
if h2.find()^=0 then h2.add();
end;
h2.output(dataset:'result2');
/*定义公司及日期2为唯一的关键字并映射到哈希表*/
run;
data result3;
length co $ 1;
if _n_=1 then do;
declare hash h3(dataset:'sample1',hashexp:16,multidata:'y');/*把sample1全部数据映射到哈希表,感谢楼下soporaeternus提醒哈希表的溢出问题,此处暂时取最大n=16*/
h3.definekey('co','date2');
h3.definedata('co','date2','pa','pb');
h3.definedone();
call missing(co,date2,pa,pb,pa_pb);
declare hiter iter3('h3');
end;
do while(not last1);
set result2 end=last1;
if h3.find()=0 then do;/*通过查找刚才输出的result2,查找与h3表匹配的记录*/
h3.has_next(result:r);/*由于你的数据日期1已经升序排列,相同关键字下最后一条观测为最靠近日期2的记录,通过find_next查找并计算*/
if r^=0 then do;
h3.find_next();
pa_pb=pa-pb;
output;
end;
if rc=0 then output;/*如果某个公司只有一条记录则输出*/
end;
end;
run;
最后由于还没碰到过这么多数据的处理,而网上说hash使用内存处理很快,若是运行出来,可否分享一下运行时间?哈哈