彼此在一小时内的所有记录

时间:2017-06-20 13:10:34

标签: sas enterprise-guide

我有一个具有ID,日期时间+一堆值字段的数据集。

这个想法是记录在一个小时之内是一个会话。每24小时只能进行一次会话。 (时间从第一条记录开始计算)

day()方法不起作用,因为一条记录可能是23:55 PM,而下一条记录可能是第二天的12:01 AM,它将是同一个会话。

我添加了rowid并执行了以下操作:

data testing;
set testing;
by subscriber_no;
prev_dt = lag(record_ts);
prev_row = lag(rowid);
time_from_last = intck("Second",record_ts,prev_dt);
if intck("Second",record_ts,prev_dt) >  -60*60 and intck("Second",record_ts,prev_dt) < 0 then
    same_session = 'yes';
else same_session = 'no';
if intck("Second",record_ts,prev_dt) >  -60*60 and intck("Second",record_ts,prev_dt) < 0 then
    rowid  =  prev_row;
else rowid = rowid;
format prev_dt datetime19.;
output;
run;

输入

ID  record_TS   rowid
52  17MAY2017:06:24:28  4
52  17MAY2017:07:16:12  5
91  05APR2017:07:04:55  6
91  05APR2017:07:23:37  7
91  05APR2017:08:04:52  8
91  05MAY2017:08:56:23  9

输入文件按ID排序并记录TS。

输出

ID  record_TS   rowid   prev_dt prev_row    time_from_last  same_session    
52  17MAY2017:06:24:28  4   28APR2017:08:51:25  3   -1632783    no  
52  17MAY2017:07:16:12  4   17MAY2017:06:24:28  4   -3104   yes 
91  05APR2017:07:04:55  6   17MAY2017:07:16:12  5   3629477 no  
91  05APR2017:07:23:37  6   05APR2017:07:04:55  6   -1122   yes 
91  05APR2017:08:04:52  7   05APR2017:07:23:37  7   -2475   yes This needs to be 6
91  05MAY2017:08:56:23  9   05APR2017:08:04:52  8   -2595091    no  

从底部开始的第二行 - rowid出现7,而我需要它来为6。

基本上我需要更改为在脚本移动之前保存的当前rowid以评估下一个。

谢谢 本

我已经实现了我需要的东西

proc sql;
    create table testing2 as
        select distinct t1.*, min(t2.record_TS) format datetime19. as from_time, max(t2.record_TS) format datetime19. as to_time
        from testing t1
        join testing t2 on t1.id_val= t2.id_val
        and intck("Second",t1.record_ts,t2.record_ts) between -3600 and 3600
    group by t1.id_val, t1.record_ts
order by t1.id_val, t1.record_ts
;

quit;

但我仍然想知道在移动评估下一行之前是否有办法提交当前行的更改。

1 个答案:

答案 0 :(得分:2)

我认为你的逻辑只是:

  1. 抓取每个ID的第一条记录的record_TS日期时间
  2. 对于后续记录,如果他们的record_TS在第一个记录的一个小时内,则将其重新编码为与第一个记录相同的rowID。
  3. 如果是这种情况,您可以使用RETAIN跟踪每个ID的第一个record_TS和rowID。这应该比lag()更容易,并允许在单个会话中有多个记录。以下似乎有效:

    data have;
      input ID  record_TS  datetime. rowid;
      format record_TS datetime.;
      cards;
    52 17MAY2017:06:24:28 4
    52 17MAY2017:07:16:12 5
    91 05APR2017:07:04:55 6
    91 05APR2017:07:23:37 7
    91 05APR2017:08:04:52 8
    91 05MAY2017:08:56:23 9
    ;
    run;
    
    data want;
      set have;
      by ID Record_TS;
      retain SessionStart SessionRowID;
      if first.ID then do;
        SessionStart=Record_TS;
        SessionRowID=RowID;
      end;
      else if (record_TS-SessionStart)<(60*60) then RowID=SessionRowID;
      drop SessionStart SessionRowID;
    run;
    

    输出:

    ID       record_TS        rowid
    
    52    17MAY17:06:24:28      4
    52    17MAY17:07:16:12      4
    91    05APR17:07:04:55      6
    91    05APR17:07:23:37      6
    91    05APR17:08:04:52      6
    91    05MAY17:08:56:23      9