在一定时间段内删除观察

时间:2014-06-23 15:15:08

标签: datetime sas time-series

所以我有一个数据集,其中包含一个股票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的所有观察结果。 问题是,我不认为这段代码效率很高,而且肯定容易出错,特别是如果有三个日期时间彼此相邻。

必须有更好的方法来做到这一点。

2 个答案:

答案 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行,因此我对此解决方案更有信心。