Hash 部分保留价值并有条件地替换观察';s值
数据集如下所示:Hash 部分保留价值并有条件地替换观察';s值,hash,sas,retain,Hash,Sas,Retain,数据集如下所示: Server IP Indicator Session_ID Time 2 1.20.54.221 A 00:00:01 2 1.20.54.221 A 00:01:00 1 1.20.54.221 Site A 00:02:00 1 1.20.54.221 B
Server IP Indicator Session_ID Time
2 1.20.54.221 A 00:00:01
2 1.20.54.221 A 00:01:00
1 1.20.54.221 Site A 00:02:00
1 1.20.54.221 B 00:05:00
2 1.20.54.221 Site B 00:08:00
2 1.20.54.221 C 00:10:00
2 1.20.54.221 C 00:15:00
1 1.20.54.221 F 01:00:00
1 1.20.54.221 F 01:05:00
2 1.20.54.221 Site F 01:08:00
上述数据集是从日志文件中读取的<代码>会话id将在服务器更改时更改(即1
->2
或2
->1
)。有些情况下,服务器会在发生更改后立即更改(即1
-->2
-->1
)。无论何时更改服务器,服务器都会记录最后一次会话id
,并在第二次浏览同一服务器时返回新的会话id
。(例如,第三次观察:Session\u id
仍然A
,第四次观察改为B
)。如果服务器以这种方式更改(即1
->2
->1
1
),它将返回A
->A
->B
->C
,其中B
由服务器2
生成,而C
由第二个1
生成
我的目标是确定记录中是否存在子组。规则是:
给定相同的IP,如果当前记录和最后记录之间的时间差不超过30分钟,
那么记录属于同一用户
我有一个指标变量site
,用于确定站点是否已更改。根据服务器是否发生变化以及时差是否小于30分钟进行标记
所需数据集:
Server IP Indicator Session_ID Time Difference Last_site
2 1.20.54.221 A 00:00:01 . .
2 1.20.54.221 A 00:01:00 59s .
1 1.20.54.221 Site A 00:02:00 1 Min .
1 1.20.54.221 A 00:05:00 3 Min Site
2 1.20.54.221 Site A 00:08:00 3 Min Site
2 1.20.54.221 A 00:10:00 2 Min Site
2 1.20.54.221 A 00:15:00 5 Min Site
1 1.20.54.221 F 01:00:00 45min .
1 1.20.54.221 F 01:05:00 5 Min .
2 1.20.54.221 Site F 01:08:00 3 Min .
data log_file;
set log;
retain _Session_id Last_site;,
* Assign value to retain ;
if indicator = "Site" then _Session_id = Session_id;
* if last_site = Site, its value has to be changed;
last_site=lag(site);
* Record that should be in another group ;
if difference >30 then Last_Site = "";
* Replace;
if last_site not eq "" then session_id = _session_id
run;
我的实现:
Server IP Indicator Session_ID Time Difference Last_site
2 1.20.54.221 A 00:00:01 . .
2 1.20.54.221 A 00:01:00 59s .
1 1.20.54.221 Site A 00:02:00 1 Min .
1 1.20.54.221 A 00:05:00 3 Min Site
2 1.20.54.221 Site A 00:08:00 3 Min Site
2 1.20.54.221 A 00:10:00 2 Min Site
2 1.20.54.221 A 00:15:00 5 Min Site
1 1.20.54.221 F 01:00:00 45min .
1 1.20.54.221 F 01:05:00 5 Min .
2 1.20.54.221 Site F 01:08:00 3 Min .
data log_file;
set log;
retain _Session_id Last_site;,
* Assign value to retain ;
if indicator = "Site" then _Session_id = Session_id;
* if last_site = Site, its value has to be changed;
last_site=lag(site);
* Record that should be in another group ;
if difference >30 then Last_Site = "";
* Replace;
if last_site not eq "" then session_id = _session_id
run;
问题是,保留变量
将在第五次观察时从A
变为B
,而我希望它保持值A
,直到我找到一个时差大于30
min的记录。(该过程将循环数十万个IP,因此效率也受到关注。)
有没有可能优雅地处理这个问题?
先谢谢你
[于6月22日编辑]
我正在考虑使用Hash对象来完成这项工作的可能性。我写了一些代码(显然它们不起作用,可能会导致语法错误)
数据测试11a;
长度标记$12 ip$32会话id$200代理上次代理$200 这是一个部分答案,因为我不知道你是如何构建“最后一个站点”的。在我看来,您想要的是检查差异是否超过30分钟/1800秒,如果“否”,会话id保持不变,如果“是”,则采用新的会话id。我可能将您的问题过于简化,但结果似乎很接近:
data have;
input (Server IP Indicator Session_ID) (:$20.) Time :time8.;
format time time8.;
cards;
2 1.20.54.221 . A 00:00:01
2 1.20.54.221 . A 00:01:00
1 1.20.54.221 Site A 00:02:00
1 1.20.54.221 . B 00:05:00
2 1.20.54.221 Site B 00:08:00
2 1.20.54.221 . C 00:10:00
2 1.20.54.221 . C 00:15:00
1 1.20.54.221 . F 01:00:00
1 1.20.54.221 . F 01:05:00
2 1.20.54.221 Site F 01:08:00
;
run;
data want;
set have;
by ip notsorted;
retain _session ' ';
if first.ip then
_session=session_id;
difference=dif(time);
if difference > 1800 then
_session=session_id;
drop session_id;
rename _session=session_id;
run;