0

我有一些关于人们收听广播的时间、时长和频道的数据。我需要创建一个变量,该变量sessions将收音机打开时出现的所有条目分组。因为数据可能包含一些错误,所以我想说,如果从一个通道周期结束到下一个通道周期结束不到五分钟,那么它仍然是同一个会话。希望一个简短的例子可以澄清。

  obs  Entry_date   Entry_time  duration(in secs) channel
   1    01/01/12      23:25:21    6000               2
   2    01/03/12      01:05:64     300               5
   3    01/05/12      12:12:35     456               5
   4    01/05/12      16:45:21     657               8

我想创建变量会话,以便

obs  Entry_date   Entry_time  duration(in secs) channel   session
   1    01/01/12      23:25:21    6000               2    1
   2    01/03/12      01:05:64     300               5    1
   3    01/05/12      12:12:35     456               5    2
   4    01/05/12      16:45:21     657               8    3

为了定义 1 个会话,我需要使用entry_timedate如果它从晚上 11 点到第二天早上),那么如果entry_time+duration + (5minutes) < entry_time(next channel)会话发生变化。这一直在杀死我,简单的数组无法解决问题,或者我使用数组的尝试没有奏效。提前致谢

4

2 回答 2

1

希望我能满足您的要求!由于您需要基于相邻行的结果,因此需要将表连接到自身。会话#s 不是连续的,但你应该明白这一点。

 create table #temp
 (obs int not null,
entry_date datetime not null,
duration int not null,
channel int not null)


--obs  Entry_date   Entry_time  duration(in secs) channel
insert #temp
select   1, '01/01/12 23:25:21', 6000, 2
 union all select 2, '01/03/12 01:05:54', 300, 5
 union all select 3, '01/05/12 12:12:35', 456, 5
 union all select 4, '01/05/12 16:45:21', 657, 8

select a.obs,
       a.entry_date,
       a.duration,
endSession = dateadd(mi,5,dateadd(mi,a.duration,a.entry_date)),
a.channel,
b.entry_date,
minOverlapping = datediff(mi,b.entry_date,
                          dateadd(mi,5,dateadd(mi,a.duration,a.entry_date))),
anotherSession = case 
          when dateadd(mi,5,dateadd(mi,a.duration,a.entry_date))<b.entry_date
    then b.obs
    else a.obs end
from #temp a
  left join #temp b on a.obs = b.obs - 1

希望这个对你有帮助

于 2013-09-10T18:02:11.507 回答
1

除了我在 OP 中所做的评论之外,以下是我使用 SAS 数据步骤的方法。我已将第 2 行的日期和时间值更改为我怀疑它们应该是的值(为了获得与 OP 中相同的结果)。这避免了必须执行自联接,这在大型数据集上可能是性能密集型的。
我已经使用了 DIF 和 LAG 函数,因此如果您要添加额外的代码(特别是 IF 语句),则需要小心。

data have;
input entry_date :mmddyy10. entry_time :time. duration channel;
format entry_date date9. entry_time time.;
datalines;
01/01/2012 23:25:21 6000 2
01/02/2012 01:05:54 300 5
01/05/2012 12:12:35 456 5
01/05/2012 16:45:21 657 8
;
run;

data want;
set have;
by entry_date entry_time; /* put in to check data is sorted correctly */
retain session 1; /* initialise session with value 1 */
session+(dif(dhms(entry_date,0,0,entry_time))-lag(duration)>300); /* increment session by 1 if time difference > 5 minutes */
run;
于 2013-09-11T10:31:53.800 回答