所以我有一个数据集,其中包含一个股票ID和一个date_time变量。我想删除date_time变量距下一个date_time 30分钟的所有观察值,并且库存相同。因此,如果我的数据集如下所示:
Date_Time|Stock_ID
01APR11: 07:50:00|Treasury
01APR11: 07:51:00|Treasury
这两项意见将被删除。到目前为止,我试图用dif和lag函数标记它们的删除。这是我的代码
data 3;
set 2;
time_diff=dif(Date_Time)/60;
same_stock=lag(Stock);
delete=.;
if abs(time_diff)<=30 AND same_stock=Stock_ID then delete=1;
run;
在此之后,我可以删除delete = 1的所有观察结果。 问题是,我不认为这段代码效率很高,而且肯定容易出错,特别是如果有三个日期时间彼此相邻。
必须有更好的方法来做到这一点。
答案 0 :(得分:0)
我说原始解决方案的危险方面是它 没有按时间顺序读取股票的记录,因此删除可能会受到源数据中记录顺序的影响。
我建议: 1)按时间顺序在datastep中处理 2)如果你的表现很关键,我会&#39;只输出最终记录(一旦逻辑正确)
顺便说一句,我不知道你真的使用数字作为表名。
/* sort data */
proc sort data=d2;
by stock Date_Time;
run;
/* or create index */
proc sql;
create index idx1 on d2 (stock Date_Time);
quit;
/* or create view and use V2 instead of D2 */
proc sql;
create view V2 as select * from D2 order by stock Date_Time;
quit;
data d3;
set d2 /* or use V2 if created the view */;
by stock Date_Time;
if first.stock = 1 then output;/* first row always kept for the stock */
else do;
time_diff=dif(Date_Time)/60;
if time_diff > 30 then output;
end;
run;
更新(没有尝试过)删除距离上次保留记录不到30秒的所有记录:
data d3;
set d2 /* or use V2 if created the view */;
retain last_kept_dt;
by stock Date_Time;
if first.stock = 1 then do;
last_kept_dt = Date_Time;
output;/* first row always kept for the stock */
end;
else do;
time_diff = (Date_Time - last_kept_dt)/60;
if time_diff > 30 then do;
output;
last_kept_dt = Date_Time;
end;
end;
run;
答案 1 :(得分:0)
我想出了一种我认为有效的方法。它添加了以下代码:
proc expand data=3 out=4 method=none;
convert delete=delete_lead1 / transformout=(lead 1);
run;
现在这给了我一个数据集,其中包含我的第一步中的删除变量和一个前导变量(delete_lead1),它将值1给我需要删除的另一行。我查看了所有的观察结果,它甚至可以同时用于4行或5行,因此我对此解决方案更有信心。