【发布时间】:2015-06-21 14:04:01
【问题描述】:
数据集如下所示:
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
上述数据集是从日志文件中读取的。 Session_id 将在服务器更改时更改(即 1 -> 2 或 2 -> 1 )。在某些情况下,服务器在发生更改后立即更改(即1---->2----->1)。每当更改服务器时,服务器将记录最后一个Session_id,并在第二次浏览同一服务器时返回一个新的Session_id。 (例如第三次观察:Session_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;
问题是,retained variable 将在第五次观察时从A 变为B,而我想让它坚持A 的值,直到我找到一个时差更大的记录比30 分钟。 (这个过程会循环超过数十万个 IP,因此效率也很重要。)
有没有可能优雅地处理问题的方法? 先感谢您。
[22/6 编辑]
我正在考虑使用 Hash Object 来完成这项工作的可能性。我写了一些代码(显然它们不起作用并且可能会导致语法错误)。
data test11a;
length mark $ 12 ip $ 32 Session_id $ 200 agent last_agent $ 200; <== the system said there is error with the type of variable and therefore I add this
Declare hash hid;
hid = _new_ hash( ordered : ' ascending');
hid.definekey('ip');
hid.definedata('Session_id');
hid.definedone();
call missing ( ip, Session_id);
do while ( not done);
set test11 end=done; <==== I have the original data-set called test11
by ip notsorted ; <==== hash object by group;
if not first.ip or not last.ip then do;
if mark = "Site" then rc= hid.add();
*if mark = "Next_Group" then hid.remove(key : ip); <=== Error
end;
if mark not eq "Site" or "Next_Group" then do;
rc=hid.find(); <==== Find matching iP and if matching ( rc=0)
* use variable _ session_id to test;
if rc = 0 then _session_id = Session_id;
end;
end;
run;
并且输出数据集只有两个观察值。谁能帮忙解释一下?
【问题讨论】: