<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Identify overlapped timeframe across rows in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822237#M324676</link>
    <description>&lt;P&gt;If missing discharge_dt means the individual has not been discharged, then you need to provide an "end_of_study" date:&amp;nbsp; Also, for the sample data you provided, there will be no days without overlap for dummyid=1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This program creates an array indexed by the range of dates for your study.&amp;nbsp; It then populates each date with the count of obs having that date.&amp;nbsp; Then all one has to do is step through the completed date history of counts:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  infile datalines truncover dsd;
  input DummyID (admission_dt discharge_dt) (:mmddyy.);
  format admission_dt discharge_dt date9.;
  datalines;
1,1/1/2018,2/28/2018
1,1/1/2018, 
1,1/27/2018,1/30/2018
1,3/15/2018, 
1,4/1/2018, 
1,4/7/2018, 
1,5/1/2018, 
1,6/1/2018, 
1,7/1/2018, 
1,8/1/2018, 
1,9/1/2018, 
1,10/1/2018, 
1,11/1/2018, 
1,12/1/2018, 
2,1/18/2018,5/22/2018
2,3/11/2018,4/30/2018
2,4/11/2018,6/22/2018
;

%let beg_study=01jan2018;
%let end_study=31dec2018;

data want (keep=dummyid overlap_level beg_phase end_phase);
  array _overlap_history {%sysevalf("&amp;amp;beg_study"d):%eval(1+%sysevalf("&amp;amp;end_study"d))} ;
  do until (last.dummyid);
    set have;
    by dummyid;
    if discharge_dt=. then discharge_dt="&amp;amp;end_study"d;
    _mind=min(admission_dt,_mind);
    _maxd=max(discharge_dt,_maxd);
    do d=admission_dt to discharge_dt;
      _overlap_history{d}=sum(_overlap_history{d},1);
    end;
  end;

  format beg_phase end_phase _mind _maxd date9.;
  end_phase=_mind-1;
  do until (end_phase=_maxd);
    beg_phase=end_phase+1;
    overlap_level=_overlap_history{beg_phase};
    do end_phase=beg_phase to "&amp;amp;end_study"d until(_overlap_history{end_phase+1}^=overlap_level);
    end;
    output;
  end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;BTW, if you are so inclined, you can replace the two statements&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  end_phase=_mind-1;
  do until (end_phase=_maxd);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;with&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  do end_phase=_mind-1 by 0 until (end_phase=_maxd);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Note the array is defined to go one day beyond END_STUDY.&amp;nbsp; This is to support the until condition in&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;    do end_phase=beg_phase to "&amp;amp;end_study"d-1 until(_overlap_history{end_phase+1}^=overlap_level);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;all the way through end_phase="*end_study"d.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sat, 09 Jul 2022 05:29:26 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2022-07-09T05:29:26Z</dc:date>
    <item>
      <title>Identify overlapped timeframe across rows</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822179#M324643</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have multiple rows of admission dates (admission_dt) and discharge dates (discharge_dt) per person (identified by DummyID) and wanted to identify if the timeframe (between admission_dt and discharge_dt) across multiple rows have any overlapped days. Any suggestion is greatly appreciated!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Below is the sample data:&lt;/P&gt;
&lt;TABLE width="222"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="64"&gt;DummyID&lt;/TD&gt;
&lt;TD width="77"&gt;admission_dt&lt;/TD&gt;
&lt;TD width="81"&gt;discharge_dt&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;1/1/2018&lt;/TD&gt;
&lt;TD&gt;2/28/2018&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;1/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;1/27/2018&lt;/TD&gt;
&lt;TD&gt;1/30/2018&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;3/15/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;4/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;4/7/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;5/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;6/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;7/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;8/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;9/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;10/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;11/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;12/1/2018&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;1/18/2018&lt;/TD&gt;
&lt;TD&gt;5/22/2018&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;3/11/2018&lt;/TD&gt;
&lt;TD&gt;4/30/2018&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;4/11/2018&lt;/TD&gt;
&lt;TD&gt;6/22/2018&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;</description>
      <pubDate>Fri, 08 Jul 2022 00:03:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822179#M324643</guid>
      <dc:creator>lizzy28</dc:creator>
      <dc:date>2022-07-08T00:03:07Z</dc:date>
    </item>
    <item>
      <title>Re: Identify overlapped timeframe across rows</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822182#M324645</link>
      <description>&lt;P&gt;I wasn't sure what missing discharge days mean so I've excluded these rows. If the meaning of missings is not yet discharged then all rows would overlap in your sample data.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One of below two options below should "show you the way".&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  infile datalines truncover dsd;
  input DummyID (admission_dt discharge_dt) (:mmddyy.);
  format admission_dt discharge_dt date9.;
  datalines;
1,1/1/2018,2/28/2018
1,1/1/2018, 
1,1/27/2018,1/30/2018
1,3/15/2018, 
1,4/1/2018, 
1,4/7/2018, 
1,5/1/2018, 
1,6/1/2018, 
1,7/1/2018, 
1,8/1/2018, 
1,9/1/2018, 
1,10/1/2018, 
1,11/1/2018, 
1,12/1/2018, 
2,1/18/2018,5/22/2018
2,3/11/2018,4/30/2018
2,4/11/2018,6/22/2018
;

proc sql;
  select 
    t1.DummyID,
    t1.admission_dt,
    t1.discharge_dt,
    t2.admission_dt as t2_admission_dt format=date9.,
    t2.discharge_dt as t2_discharge_dt format=date9.
  from 
    have t1
    left join 
    have t2
  on
    not missing (t1.discharge_dt)
    and
    (
      t2.admission_dt &amp;lt; t1.admission_dt &amp;lt; t2.discharge_dt
      or
      t2.admission_dt &amp;lt; t1.discharge_dt &amp;lt; t2.discharge_dt
    )
  order by t1.DummyID, t1.admission_dt
  ;
quit;


proc sql;
  select 
    t1.DummyID,
    t1.admission_dt,
    t1.discharge_dt,
    count(*) as n_overlaps
  from 
    have t1
    left join 
    have t2
  on
    not missing (t1.discharge_dt)
    and
    (
      t2.admission_dt &amp;lt; t1.admission_dt &amp;lt; t2.discharge_dt
      or
      t2.admission_dt &amp;lt; t1.discharge_dt &amp;lt; t2.discharge_dt
    )
  group by t1.DummyID, t1.admission_dt, t1.discharge_dt
  ;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Patrick_0-1657240697073.png" style="width: 370px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/73043i3EE716C3FDFD56E3/image-dimensions/370x759?v=v2" width="370" height="759" role="button" title="Patrick_0-1657240697073.png" alt="Patrick_0-1657240697073.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 08 Jul 2022 00:38:32 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822182#M324645</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2022-07-08T00:38:32Z</dc:date>
    </item>
    <item>
      <title>Re: Identify overlapped timeframe across rows</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822198#M324652</link>
      <description>Thank you, Patrick! &lt;BR /&gt;&lt;BR /&gt;I forgot to mention that missing discharge date means one has not been discharged. So this case the rows are technically all overlapped per individual.</description>
      <pubDate>Fri, 08 Jul 2022 02:42:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822198#M324652</guid>
      <dc:creator>lizzy28</dc:creator>
      <dc:date>2022-07-08T02:42:33Z</dc:date>
    </item>
    <item>
      <title>Re: Identify overlapped timeframe across rows</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822237#M324676</link>
      <description>&lt;P&gt;If missing discharge_dt means the individual has not been discharged, then you need to provide an "end_of_study" date:&amp;nbsp; Also, for the sample data you provided, there will be no days without overlap for dummyid=1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This program creates an array indexed by the range of dates for your study.&amp;nbsp; It then populates each date with the count of obs having that date.&amp;nbsp; Then all one has to do is step through the completed date history of counts:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  infile datalines truncover dsd;
  input DummyID (admission_dt discharge_dt) (:mmddyy.);
  format admission_dt discharge_dt date9.;
  datalines;
1,1/1/2018,2/28/2018
1,1/1/2018, 
1,1/27/2018,1/30/2018
1,3/15/2018, 
1,4/1/2018, 
1,4/7/2018, 
1,5/1/2018, 
1,6/1/2018, 
1,7/1/2018, 
1,8/1/2018, 
1,9/1/2018, 
1,10/1/2018, 
1,11/1/2018, 
1,12/1/2018, 
2,1/18/2018,5/22/2018
2,3/11/2018,4/30/2018
2,4/11/2018,6/22/2018
;

%let beg_study=01jan2018;
%let end_study=31dec2018;

data want (keep=dummyid overlap_level beg_phase end_phase);
  array _overlap_history {%sysevalf("&amp;amp;beg_study"d):%eval(1+%sysevalf("&amp;amp;end_study"d))} ;
  do until (last.dummyid);
    set have;
    by dummyid;
    if discharge_dt=. then discharge_dt="&amp;amp;end_study"d;
    _mind=min(admission_dt,_mind);
    _maxd=max(discharge_dt,_maxd);
    do d=admission_dt to discharge_dt;
      _overlap_history{d}=sum(_overlap_history{d},1);
    end;
  end;

  format beg_phase end_phase _mind _maxd date9.;
  end_phase=_mind-1;
  do until (end_phase=_maxd);
    beg_phase=end_phase+1;
    overlap_level=_overlap_history{beg_phase};
    do end_phase=beg_phase to "&amp;amp;end_study"d until(_overlap_history{end_phase+1}^=overlap_level);
    end;
    output;
  end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;BTW, if you are so inclined, you can replace the two statements&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  end_phase=_mind-1;
  do until (end_phase=_maxd);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;with&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  do end_phase=_mind-1 by 0 until (end_phase=_maxd);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Note the array is defined to go one day beyond END_STUDY.&amp;nbsp; This is to support the until condition in&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;    do end_phase=beg_phase to "&amp;amp;end_study"d-1 until(_overlap_history{end_phase+1}^=overlap_level);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;all the way through end_phase="*end_study"d.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 09 Jul 2022 05:29:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Identify-overlapped-timeframe-across-rows/m-p/822237#M324676</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2022-07-09T05:29:26Z</dc:date>
    </item>
  </channel>
</rss>

