<?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: Date Merging With range in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652413#M195859</link>
    <description>&lt;P&gt;If the data sets are sorted by id and date, as they are in your sample, then this is a good situation for conditional SET statements in a DATA step, as in:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data aa;
input id order MMDDYY10.;
format order MMDDYY10.;
cards;
20 7/16/2016
20 10/2/2017
30 7/17/2016
38 7/18/2016
;

data bb;
input id name $ received MMDDYY10.;
format received MMDDYY10.;
cards;
20 EG 7/26/2016
20 TP 7/26/2016
20 TP 10/22/2017
20 EG 10/22/2017
30 TP 8/1/2016
30 ER 8/1/2016
30 CD 8/1/2016
30 KR 8/1/2016
38 KR 8/3/2016
38 TP 8/3/2016
38 CD 8/3/2016
38 PI 8/3/2016
;
data want (drop=_date);
  set aa (rename=(order=_date) in=inaa)
      bb (rename=(received=_date) in=inbb);
  by id _date;
  if inaa then set aa;
  if inbb then set bb;
  if lag(inaa)=1 and inbb=1 and first.id=0;
run; 
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The first SET statement interleaves the two data sets by ID and _DATE (renamed from ORDER and RECEIVED respectively).&amp;nbsp; The conditional SETS re-read AA or BB, but with the order and received variables not renamed.&amp;nbsp; This means their values will not be replaced until another record from the same data set is read, i.e. RECEIVED and ORDER are "retained".&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In turn, all you have to do is keep the instance in which the current record is from BB and the immediately preceding record is from AA.&amp;nbsp; The "and first.id=0" condition avoids instances in which one ID ends with an AA record, and the next ID begins with a BB record.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This is a good example of the robustness of the DATA step, requiring much less record comparison than SQL, at least when the data sets are sorted.&lt;/P&gt;</description>
    <pubDate>Tue, 02 Jun 2020 02:31:52 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2020-06-02T02:31:52Z</dc:date>
    <item>
      <title>Date Merging With range</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652396#M195848</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;&lt;P&gt;I did quite a bit of research on merging dates by ranges on this forum. Here are my 2 datasets. I want to be able to merge the rows by closest date range.&lt;/P&gt;&lt;P&gt;The order dates (in data set AA) occur before the received dates (in dataset BB)&lt;/P&gt;&lt;P&gt;I also have the code that used below:&lt;/P&gt;&lt;P&gt;Data set AA&lt;/P&gt;&lt;TABLE border="0" cellspacing="0" cellpadding="0"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;ID&lt;/TD&gt;&lt;TD&gt;Order&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;7/16/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;10/2/2017&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;7/17/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;7/18/2016&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Data set BB: Some of the IDs received the product on the same date: For example, ID=20 received products EGF and TP on the same date.&amp;nbsp;&lt;/P&gt;&lt;TABLE border="0" cellspacing="0" cellpadding="0"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;ID&lt;/TD&gt;&lt;TD&gt;name&lt;/TD&gt;&lt;TD&gt;Received&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;EGF&lt;/TD&gt;&lt;TD&gt;7/26/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;TP&lt;/TD&gt;&lt;TD&gt;7/26/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;TP&lt;/TD&gt;&lt;TD&gt;10/22/2017&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;EGF&lt;/TD&gt;&lt;TD&gt;10/22/2017&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;TP&lt;/TD&gt;&lt;TD&gt;8/1/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;ER&lt;/TD&gt;&lt;TD&gt;8/1/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;CDK&lt;/TD&gt;&lt;TD&gt;8/1/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;KRA&lt;/TD&gt;&lt;TD&gt;8/1/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;KRA&lt;/TD&gt;&lt;TD&gt;8/3/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;TP&lt;/TD&gt;&lt;TD&gt;8/3/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;CDK&lt;/TD&gt;&lt;TD&gt;8/3/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;PIK&lt;/TD&gt;&lt;TD&gt;8/3/2016&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is the final dataset i would like to have. It has the same rows as the dataset AA.&amp;nbsp;&lt;/P&gt;&lt;TABLE border="0" cellspacing="0" cellpadding="0"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;ID&lt;/TD&gt;&lt;TD&gt;Order&lt;/TD&gt;&lt;TD&gt;Received&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;7/16/2016&lt;/TD&gt;&lt;TD&gt;7/26/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;20&lt;/TD&gt;&lt;TD&gt;10/2/2017&lt;/TD&gt;&lt;TD&gt;10/22/2017&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;30&lt;/TD&gt;&lt;TD&gt;7/17/2016&lt;/TD&gt;&lt;TD&gt;8/1/2016&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;38&lt;/TD&gt;&lt;TD&gt;7/18/2016&lt;/TD&gt;&lt;TD&gt;8/3/2016&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data aa;&lt;BR /&gt;input id order MMDDYY10.;&lt;BR /&gt;format order MMDDYY10.;&lt;BR /&gt;cards;&lt;BR /&gt;20 7/16/2016&lt;BR /&gt;20 10/2/2017&lt;BR /&gt;30 7/17/2016&lt;BR /&gt;38 7/18/2016&lt;BR /&gt;;&lt;/P&gt;&lt;P&gt;data bb;&lt;BR /&gt;input id name $ received MMDDYY10.;&lt;BR /&gt;format received MMDDYY10.;&lt;BR /&gt;cards;&lt;BR /&gt;20 EG 7/26/2016&lt;BR /&gt;20 TP 7/26/2016&lt;BR /&gt;20 TP 10/22/2017&lt;BR /&gt;20 EG 10/22/2017&lt;BR /&gt;30 TP 8/1/2016&lt;BR /&gt;30 ER 8/1/2016&lt;BR /&gt;30 CD 8/1/2016&lt;BR /&gt;30 KR 8/1/2016&lt;BR /&gt;38 KR 8/3/2016&lt;BR /&gt;38 TP 8/3/2016&lt;BR /&gt;38 CD 8/3/2016&lt;BR /&gt;38 PI 8/3/2016&lt;BR /&gt;;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;PROC SQL;&lt;BR /&gt;CREATE TABLE want AS&lt;BR /&gt;SELECT&lt;BR /&gt;A.*,&lt;BR /&gt;B.received,&lt;BR /&gt;FROM&lt;BR /&gt;aa A&lt;BR /&gt;join&lt;BR /&gt;bb B&lt;BR /&gt;ON&lt;BR /&gt;A.ID=B.ID&lt;BR /&gt;AND&lt;BR /&gt;A.order &amp;lt; B.Received&lt;BR /&gt;;&lt;BR /&gt;QUIT;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here i also tried to get a dataset in a different format. Basically have the same rows as dataset BB and have the closest dates&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want;&lt;BR /&gt;merge aa(in=a) bb(in=b) ;&lt;BR /&gt;by ID;&lt;BR /&gt;if order&amp;lt;received then output;&lt;BR /&gt;run;&lt;/P&gt;</description>
      <pubDate>Tue, 02 Jun 2020 00:06:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652396#M195848</guid>
      <dc:creator>rajd1</dc:creator>
      <dc:date>2020-06-02T00:06:18Z</dc:date>
    </item>
    <item>
      <title>Re: Date Merging With range</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652400#M195851</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/331278"&gt;@rajd1&lt;/a&gt;&amp;nbsp; Assuming I understand your description correctly, the solution is pretty straight for&lt;SPAN&gt;ward-&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
data aa;
input id order MMDDYY10.;
format order MMDDYY10.;
cards;
20 7/16/2016
20 10/2/2017
30 7/17/2016
38 7/18/2016
;

data bb;
input id name $ received MMDDYY10.;
format received MMDDYY10.;
cards;
20 EG 7/26/2016
20 TP 7/26/2016
20 TP 10/22/2017
20 EG 10/22/2017
30 TP 8/1/2016
30 ER 8/1/2016
30 CD 8/1/2016
30 KR 8/1/2016
38 KR 8/3/2016
38 TP 8/3/2016
38 CD 8/3/2016
38 PI 8/3/2016
;

proc sql;
create table want  as
select distinct a.*,b.received
from aa a left join bb b
on a.id=b.id and order&amp;lt;=received
group by a.id,order
having min(received)=received;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 02 Jun 2020 00:33:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652400#M195851</guid>
      <dc:creator>novinosrin</dc:creator>
      <dc:date>2020-06-02T00:33:29Z</dc:date>
    </item>
    <item>
      <title>Re: Date Merging With range</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652412#M195858</link>
      <description>That worked perfectly!! Thanks so much &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;</description>
      <pubDate>Tue, 02 Jun 2020 02:26:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652412#M195858</guid>
      <dc:creator>rajd1</dc:creator>
      <dc:date>2020-06-02T02:26:33Z</dc:date>
    </item>
    <item>
      <title>Re: Date Merging With range</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652413#M195859</link>
      <description>&lt;P&gt;If the data sets are sorted by id and date, as they are in your sample, then this is a good situation for conditional SET statements in a DATA step, as in:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data aa;
input id order MMDDYY10.;
format order MMDDYY10.;
cards;
20 7/16/2016
20 10/2/2017
30 7/17/2016
38 7/18/2016
;

data bb;
input id name $ received MMDDYY10.;
format received MMDDYY10.;
cards;
20 EG 7/26/2016
20 TP 7/26/2016
20 TP 10/22/2017
20 EG 10/22/2017
30 TP 8/1/2016
30 ER 8/1/2016
30 CD 8/1/2016
30 KR 8/1/2016
38 KR 8/3/2016
38 TP 8/3/2016
38 CD 8/3/2016
38 PI 8/3/2016
;
data want (drop=_date);
  set aa (rename=(order=_date) in=inaa)
      bb (rename=(received=_date) in=inbb);
  by id _date;
  if inaa then set aa;
  if inbb then set bb;
  if lag(inaa)=1 and inbb=1 and first.id=0;
run; 
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The first SET statement interleaves the two data sets by ID and _DATE (renamed from ORDER and RECEIVED respectively).&amp;nbsp; The conditional SETS re-read AA or BB, but with the order and received variables not renamed.&amp;nbsp; This means their values will not be replaced until another record from the same data set is read, i.e. RECEIVED and ORDER are "retained".&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In turn, all you have to do is keep the instance in which the current record is from BB and the immediately preceding record is from AA.&amp;nbsp; The "and first.id=0" condition avoids instances in which one ID ends with an AA record, and the next ID begins with a BB record.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This is a good example of the robustness of the DATA step, requiring much less record comparison than SQL, at least when the data sets are sorted.&lt;/P&gt;</description>
      <pubDate>Tue, 02 Jun 2020 02:31:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Date-Merging-With-range/m-p/652413#M195859</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-06-02T02:31:52Z</dc:date>
    </item>
  </channel>
</rss>

