<?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: Forward Lookups and Conditional Values in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908524#M358521</link>
    <description>&lt;P&gt;Given the data are sorted by ID/DATE, you could make a dataset FLAG_DATES, based on the non-"P" observations, with an observation for the date a flag could become 1 (i.e. 6 months before the earliest non-"P" category, and another for when it must become zero (the latest date for a non-"P" that sufficiently overlaps with the other non-"P").&amp;nbsp; This could accommodate instances of multiple non-overlapping "_flag=1" windows for a single ID.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then you could use a MERGE of that dataset with the original dataset HAVE, accompanied by a conditional SET statement to automatically retain the _FLAG value, as in:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have ;
  input ID $1. +1 Date date9. +1 Category $1.;
  format date date9.;
cards;
A 31-Jan-21 P
A 28-Feb-21 P
A 30-Jun-21 U
A 30-Jul-21 U
A 30-Sep-21 C
B 31-Jan-21 P
B 28-Feb-21 P
B 30-Sep-21 U
B 31-Oct-21 U
B 31-Dec-21 C
run;

data flag_dates (keep=id date _flag ) / view=flag_dates;
  set have (where=(category^='P')) ;
  by id;

  _flag=1;
  date=intnx('month',date,-6);
  if first.id=1 or intck('month',lag(date),date)&amp;gt;6 then output;

  merge have (where=(category^='P'))                /*Re-read DATE and get NXT_DATE */
        have (firstobs=2 where=(category^='P') keep=category date rename=(date=nxt_date)) ;

  _flag=0;
  if last.id=1  or intck('month',date,nxt_date)&amp;gt;6 then output;
run;


data want (drop=_:);
  merge have (in=keep) flag_dates (in=inflg drop=_flag);
  by id date;

  if inflg=1 then set flag_dates (keep=_flag);
  if keep;
  if category='P' then flag=coalesce(_flag,0);
  else flag=0;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You might have to change the calculation of the DATE values in FLAG_DATES.&amp;nbsp; For instance, the&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  date=intnx('month',date,-6);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;statement generates a 6-month prior at the &lt;EM&gt;&lt;STRONG&gt;beginning&lt;/STRONG&gt;&lt;/EM&gt; for 6-months prior (i.e. 1st of the month).&amp;nbsp; You might want the "same day of month" calculation (so modify the INTNX function).&amp;nbsp; And you'll have to decide whether that date is within the window, or just outside of it.&amp;nbsp; I.e. you might need to add 1 to the resulting date value.&amp;nbsp; Same concept will need to be applied when considering whether the interval from the current DATE to the NXT_DATE is small enough to extend the end-of-window to next date.&lt;/P&gt;</description>
    <pubDate>Sun, 17 Dec 2023 22:13:03 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2023-12-17T22:13:03Z</dc:date>
    <item>
      <title>Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908473#M358499</link>
      <description>&lt;P&gt;I have a dataset like following where I need a flag when Category changed from "P" to any other category during 6 months from last occurrence of category "P" and that flag has to be populated where Category is "P" based on forward lookups -&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;ID&lt;/TD&gt;&lt;TD&gt;Date&lt;/TD&gt;&lt;TD&gt;Category&lt;/TD&gt;&lt;TD&gt;Flag(want)&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A&lt;/TD&gt;&lt;TD&gt;31-Jan-21&lt;/TD&gt;&lt;TD&gt;P&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A&lt;/TD&gt;&lt;TD&gt;28-Feb-21&lt;/TD&gt;&lt;TD&gt;P&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A&lt;/TD&gt;&lt;TD&gt;30-Jun-21&lt;/TD&gt;&lt;TD&gt;U&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A&lt;/TD&gt;&lt;TD&gt;30-Jul-21&lt;/TD&gt;&lt;TD&gt;U&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A&lt;/TD&gt;&lt;TD&gt;30-Sep-21&lt;/TD&gt;&lt;TD&gt;C&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;31-Jan-21&lt;/TD&gt;&lt;TD&gt;P&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;28-Feb-21&lt;/TD&gt;&lt;TD&gt;P&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;30-Sep-21&lt;/TD&gt;&lt;TD&gt;U&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;31-Oct-21&lt;/TD&gt;&lt;TD&gt;U&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;31-Dec-21&lt;/TD&gt;&lt;TD&gt;C&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any help is deeply appreciated.&lt;/P&gt;</description>
      <pubDate>Sat, 16 Dec 2023 11:42:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908473#M358499</guid>
      <dc:creator>thepushkarsingh</dc:creator>
      <dc:date>2023-12-16T11:42:25Z</dc:date>
    </item>
    <item>
      <title>Re: Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908478#M358502</link>
      <description>&lt;P&gt;Please present your data as a data step, e.g.:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input ID $1. +1 Date date9. +1 Category $1.;
  format date date9.;
cards;
A 31-Jan-21 P
A 28-Feb-21 P
A 30-Jun-21 U
A 30-Jul-21 U
A 30-Sep-21 C
B 31-Jan-21 P
B 28-Feb-21 P
B 30-Sep-21 U
B 31-Oct-21 U
B 31-Dec-21 C
;run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;One way to do it is to catch the changes and then use SQL to get the flag:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data changes;
  set have;
  by ID Category notsorted;
  if first.category and not first.id;
run;

proc sql;
  create table want as select *,
    case when category='P' then
    exists(select * from changes where ID=have.id 
                                 and date&amp;gt;have.date and date&amp;lt;=intnx('month',have.date,6,'S')) 
    else 0
    end as Flag
  from have;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 16 Dec 2023 13:12:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908478#M358502</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2023-12-16T13:12:50Z</dc:date>
    </item>
    <item>
      <title>Re: Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908524#M358521</link>
      <description>&lt;P&gt;Given the data are sorted by ID/DATE, you could make a dataset FLAG_DATES, based on the non-"P" observations, with an observation for the date a flag could become 1 (i.e. 6 months before the earliest non-"P" category, and another for when it must become zero (the latest date for a non-"P" that sufficiently overlaps with the other non-"P").&amp;nbsp; This could accommodate instances of multiple non-overlapping "_flag=1" windows for a single ID.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then you could use a MERGE of that dataset with the original dataset HAVE, accompanied by a conditional SET statement to automatically retain the _FLAG value, as in:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have ;
  input ID $1. +1 Date date9. +1 Category $1.;
  format date date9.;
cards;
A 31-Jan-21 P
A 28-Feb-21 P
A 30-Jun-21 U
A 30-Jul-21 U
A 30-Sep-21 C
B 31-Jan-21 P
B 28-Feb-21 P
B 30-Sep-21 U
B 31-Oct-21 U
B 31-Dec-21 C
run;

data flag_dates (keep=id date _flag ) / view=flag_dates;
  set have (where=(category^='P')) ;
  by id;

  _flag=1;
  date=intnx('month',date,-6);
  if first.id=1 or intck('month',lag(date),date)&amp;gt;6 then output;

  merge have (where=(category^='P'))                /*Re-read DATE and get NXT_DATE */
        have (firstobs=2 where=(category^='P') keep=category date rename=(date=nxt_date)) ;

  _flag=0;
  if last.id=1  or intck('month',date,nxt_date)&amp;gt;6 then output;
run;


data want (drop=_:);
  merge have (in=keep) flag_dates (in=inflg drop=_flag);
  by id date;

  if inflg=1 then set flag_dates (keep=_flag);
  if keep;
  if category='P' then flag=coalesce(_flag,0);
  else flag=0;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You might have to change the calculation of the DATE values in FLAG_DATES.&amp;nbsp; For instance, the&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  date=intnx('month',date,-6);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;statement generates a 6-month prior at the &lt;EM&gt;&lt;STRONG&gt;beginning&lt;/STRONG&gt;&lt;/EM&gt; for 6-months prior (i.e. 1st of the month).&amp;nbsp; You might want the "same day of month" calculation (so modify the INTNX function).&amp;nbsp; And you'll have to decide whether that date is within the window, or just outside of it.&amp;nbsp; I.e. you might need to add 1 to the resulting date value.&amp;nbsp; Same concept will need to be applied when considering whether the interval from the current DATE to the NXT_DATE is small enough to extend the end-of-window to next date.&lt;/P&gt;</description>
      <pubDate>Sun, 17 Dec 2023 22:13:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908524#M358521</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2023-12-17T22:13:03Z</dc:date>
    </item>
    <item>
      <title>Re: Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908535#M358528</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
Assuming I understood what you mean.
And your dataset has been sorted by ID and DATE.
*/

data have ;
  input ID $1. +1 Date date9. +1 Category $1.;
  format date date9.;
cards;
A 31-Jan-21 P
A 28-Feb-21 P
A 30-Jun-21 U
A 30-Jul-21 U
A 30-Sep-21 C
B 31-Jan-21 P
B 28-Feb-21 P
B 30-Sep-21 U
B 31-Oct-21 U
B 31-Dec-21 C
;


data temp;
 set have;
 by id Category notsorted;
 group+first.Category;
run;
data key;
 merge temp temp(keep=id date Category rename=(id=_id date=_date Category=_Category ) firstobs=2);
 if id=_id and Category='P' and _Category ne 'P' and .&amp;lt;intck('month',date,_date,'c')&amp;lt;=6;
 keep group;
run;
data want;
 if _n_=1 then do;
  if 0 then set key;
  declare hash h(dataset:'key');
  h.definekey('group');
  h.definedone();
 end;
set temp;
flag= ( h.check()=0 );
run; &lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 18 Dec 2023 02:35:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908535#M358528</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-12-18T02:35:40Z</dc:date>
    </item>
    <item>
      <title>Re: Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908557#M358533</link>
      <description>Many thanks, though it takes quite a long to complete on my dataset, almost 4 hrs!</description>
      <pubDate>Mon, 18 Dec 2023 08:15:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908557#M358533</guid>
      <dc:creator>thepushkarsingh</dc:creator>
      <dc:date>2023-12-18T08:15:18Z</dc:date>
    </item>
    <item>
      <title>Re: Forward Lookups and Conditional Values</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908558#M358534</link>
      <description>Thank you so much, this is most efficient on my large dataset.</description>
      <pubDate>Mon, 18 Dec 2023 08:16:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Forward-Lookups-and-Conditional-Values/m-p/908558#M358534</guid>
      <dc:creator>thepushkarsingh</dc:creator>
      <dc:date>2023-12-18T08:16:02Z</dc:date>
    </item>
  </channel>
</rss>

