Location Start End Diff
A 01:02:00 01:05:00 3
A 01:03:00 01:08:00 5
A 01:04:00 01:11:00 7
B 02:00:00 02:17:00 17
B 02:10:00 02:20:00 10
B 02:11:00 02:15:00 4
理想输出:
Location OverlapTime(Min) OverlapRecords
A 6 3
B 11 3
如果每次只有同一位置的两个记录重叠,那么我可以通过lag
data want;
set have;
prevend = lag1(End);
if first.location then prevend = .;
if start < prevend then overlap = 1;else overlap = 0;
overlaptime = -(start-prevend);
by location notsorted;
run;
proc sql;
select location, sum(overlaptime), sum(overlap)
from want
group by location;
但问题是,我在同一位置有很多(未知)重叠时间间隔。我怎样才能做到这一点?
答案 0 :(得分:1)
这是我的解决方案。无需使用lag
功能,可以使用retain
语句以及first
和last
完成此操作。
/* create dummy dataset */
data have;
input Location $ Start :time. End :time.;
format start end time.;
datalines;
A 01:02:00 01:05:00
A 01:03:00 01:08:00
A 01:04:00 01:11:00
A 01:13:00 01:15:00
B 02:00:00 02:17:00
B 02:10:00 02:20:00
B 02:11:00 02:15:00
C 01:25:00 01:30:00
D 01:45:00 01:50:00
D 01:51:00 01:55:00
;
run;
/* sort data if necessary */
proc sort data = have;
by location start;
run;
/* calculate overlap */
data want;
set have;
by location start;
retain _stime _etime _gap overlaprecords; /* retain temporary variables from previous row */
if first.location then do; /* reset temporary and new variables at each change in location */
_stime = start;
_etime = end;
_gap = 0;
_cumul_diff = 0;
overlaprecords=0;
end;
_cumul_diff + (end-start); /* calculate cumulative difference between start and end */
if start>_etime then _gap + (start-_etime); /* calculate gap between start time and previous highest end time */
if not first.location and start<_etime then do; /* count number of overlap records */
if overlaprecords=0 then overlaprecords+2; /* first overlap record gets count of 2 to account for previous record */
else overlaprecords + 1;
end;
if end>_etime then _etime=end; /* update _etime if end is greater than current value */
if last.location then do; /* calculate overlap time when last record for current location is read */
overlaptime = intck('minute',(_etime-_stime-_gap),_cumul_diff);
output;
end;
drop _: start end; /* drop unanted variables */
run;