Sas 所有的记录在一个小时内互相交换

Sas 所有的记录在一个小时内互相交换,sas,enterprise-guide,Sas,Enterprise Guide,我有一个数据集,它有ID、datetime+一组值字段 这个想法是,在一个会话中,记录之间的间隔不超过一个小时。每24小时只能有一次会话。(从第一条记录开始测量时间) day()方法不起作用,因为一条记录可能是晚上23:55,下一条记录可能是第二天上午12:01,并且是同一个会话 我添加了rowid并运行了以下操作: data testing; set testing; by subscriber_no; prev_dt = lag(record_ts); prev_row = lag(rowi

我有一个数据集,它有ID、datetime+一组值字段

这个想法是,在一个会话中,记录之间的间隔不超过一个小时。每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和记录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,以评估下一个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;

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

我认为您的逻辑是:

  • 抓取每个ID的第一条记录的日期时间
  • 对于后续记录,如果其记录在第一条记录的一小时内,则将其重新编码为与第一条记录相同的rowID
  • 如果是这种情况,可以使用RETAIN跟踪每个ID的第一条记录和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的第一条记录的日期时间
  • 对于后续记录,如果其记录在第一条记录的一小时内,则将其重新编码为与第一条记录相同的rowID
  • 如果是这种情况,可以使用RETAIN跟踪每个ID的第一条记录和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;
    

    为什么不创建一个“Session”表,每个Session有一行,并定义一个
    ExpiresAt
    日期,即未来24小时。然后,每次用户发出请求时,将
    ExpiresAt
    更新为24小时后。这就是我要做的。我无法更改源表的结构或可用数据。您是否可以将数据(即输入数据集)添加到问题中?订阅者_是否没有变量输出中打印的ID?我注意到您有一个订户的
    \u no语句,但没有阻止两个不同订阅者被分配到同一会话的逻辑。一般来说,输入和输出数据集相同是一个坏主意,即使只是在测试时也是如此,因为这样很难重复测试和检查结果。为什么不创建一个“会话”表,每个会话有一行,并定义一个
    ExpiresAt
    日期,即未来24小时。然后,每次用户发出请求时,将
    ExpiresAt
    更新为24小时后。这就是我要做的。我无法更改源表的结构或可用数据。您是否可以将数据(即输入数据集)添加到问题中?订阅者_是否没有变量输出中打印的ID?我注意到您有一个订户的
    \u no语句,但没有阻止两个不同订阅者被分配到同一会话的逻辑。通常,输入和输出数据集相同是一个坏主意,即使只是在测试时也是如此,因为这样很难重复测试和检查结果。
    
    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