我有一些关于人们收听收音机的时间,时长和频道的数据。我需要创建一个名为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_time(如果从晚上11点到第二天早晨,则为日期),以便如果entry_time + duration +(5minutes)< entry_time(下一个频道)然后会话改变。这已经杀了我,简单的数组不会做这个技巧,或者我使用数组的尝试没有用。提前致谢
答案 0 :(得分:1)
希望我的要求合适! 由于您需要将结果基于相邻的行,因此需要将表连接到自身。 Session #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
希望这有点帮助
答案 1 :(得分: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;