我有一个具有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;
但我仍然想知道在移动评估下一行之前是否有办法提交当前行的更改。
答案 0 :(得分:2)
我认为你的逻辑只是:
如果是这种情况,您可以使用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