一个小时内的所有记录

All the records within an hour of each other

我有一个包含 ID、日期时间 + 一堆值字段的数据集。

想法是记录在一小时内彼此是一个会话。每 24 小时只能有一个会话。 (时间从第一条记录开始计算)

day() 方法不起作用,因为一个记录可以是 23:55 下午,下一个记录可以是第二天 12:01 上午,这将是同一个会话。

我添加了 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. 抓取每个 ID 的第一条记录的 record_TS 日期时间
  2. 对于后续记录,如果它们的 record_TS 在第一条记录的一个小时内,将其重新编码为与第一条记录相同的 rowID。

如果是这种情况,您可以使用 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