data want (drop=_:);
set have (keep=source target);
by source target notsorted;
merge have (rename=(start=_current_start))
have (firstobs=2 keep=start rename=(start=_nxt_start));
retain start ;
format start yymmddn8. ;
if first.target=1 or _current_start-1>lag(end) then start=_current_start;
if last.target=1 or end+1<_nxt_start;
run;
The SET and MERGE statement set up two streams of data, read in parallel.
The first SET is accompanied by the BY statement, allowing use of first.target and last.target dummies. The data are assumed to be grouped by source*target, and within each source*target group, to be sorted by start. (and also sorted by END within each group).
The MERGE statement has two "substreams" of data, also read in parallel, but because of the FIRSTOBS=2 option provides a way to look ahead at the upcoming START value (in variable _nxt_start), so upcoming date gaps can easily be found.
The first IF identifies the beginning of a continuous sequence of observations.
The second if identified the end of same.
... View more