<?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: How to use LAG function in an iterative way? in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534511#M146673</link>
    <description>&lt;P&gt;Forget about an iterative lag.&amp;nbsp; In fact, forget about lag entirely.&amp;nbsp; Just hold onto the flag value once you calculate it.&amp;nbsp; For example:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
set have;
by id;
if first.id then flag=.;
if variable1 &amp;lt; -105 then flag=1;
retain flag;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This only works if FLAG is a newly created variable, not part of the incoming data.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Unless there is a more complex definition of what "every subsequent case" means, this should do it.&lt;/P&gt;</description>
    <pubDate>Mon, 11 Feb 2019 16:11:47 GMT</pubDate>
    <dc:creator>Astounding</dc:creator>
    <dc:date>2019-02-11T16:11:47Z</dc:date>
    <item>
      <title>How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534485#M146667</link>
      <description>&lt;P&gt;I have first used the following syntax to produce a flag which finds the first instance, within the same ID, where a value for variable1 is found with a value of &amp;lt;-105:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;IF (ID=LAG(ID) AND variable1&amp;lt;-105 AND LAG(variable1) GE -105) THEN FLAG=1;
RUN;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;What I would then like to do is flag every subsequent case after the one I have just flagged, within the same ID. So far I can only flag the one that is directly beneath the initial one I flagged using this syntax:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;IF (ID=LAG(ID) AND LAG(flag)=1) THEN FLAG=1;
RUN;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Is there a way to run this code so that it flags every subsequent case following that initial flag, within the same ID?&lt;/P&gt;</description>
      <pubDate>Mon, 11 Feb 2019 15:10:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534485#M146667</guid>
      <dc:creator>djohn051</dc:creator>
      <dc:date>2019-02-11T15:10:47Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534509#M146671</link>
      <description>You should never be using ID=lag(ID) in SAS except in rare circumstances. Instead, use BY group processing, much more effective. LAG() functions don't work in conditional statements so you need to pull it out of the conditional IF and calculate it regardless. You can set it to missing after, conditionally.</description>
      <pubDate>Mon, 11 Feb 2019 16:07:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534509#M146671</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2019-02-11T16:07:54Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534511#M146673</link>
      <description>&lt;P&gt;Forget about an iterative lag.&amp;nbsp; In fact, forget about lag entirely.&amp;nbsp; Just hold onto the flag value once you calculate it.&amp;nbsp; For example:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
set have;
by id;
if first.id then flag=.;
if variable1 &amp;lt; -105 then flag=1;
retain flag;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This only works if FLAG is a newly created variable, not part of the incoming data.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Unless there is a more complex definition of what "every subsequent case" means, this should do it.&lt;/P&gt;</description>
      <pubDate>Mon, 11 Feb 2019 16:11:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534511#M146673</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2019-02-11T16:11:47Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534533#M146682</link>
      <description>&lt;P&gt;It is a bit more complicated than that. The &amp;lt;-105 rule is only to identify the initial case. What I want after that is for every subsequent case (they are already sorted by date) to be flagged as 1, within that given ID, regardless of if the value is &amp;lt; or &amp;gt;= -105.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Does that make sense?&lt;/P&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:00:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534533#M146682</guid>
      <dc:creator>djohn051</dc:creator>
      <dc:date>2019-02-11T17:00:08Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534537#M146683</link>
      <description>&lt;P&gt;Then go for:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
flag = 0;
do until(last.id);
    set have; by id notsorted;
    if variable1 &amp;lt; -105 then flag = 1;
    output;
    end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:15:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534537#M146683</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2019-02-11T17:15:54Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534542#M146685</link>
      <description>&lt;P&gt;This seems to have flagged every case as =1&lt;/P&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:28:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534542#M146685</guid>
      <dc:creator>djohn051</dc:creator>
      <dc:date>2019-02-11T17:28:49Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534546#M146688</link>
      <description>&lt;P&gt;Only if the first value of variable1 is &amp;lt;-105 or missing in every id group.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
do id = 1, 2, 3;
    do variable1 = 1, 2, -200, 3;
        output;
        end;
    end;
run;

data want;
flag = 0;
do until(last.id);
    set have; by id notsorted;
    if variable1 &amp;lt; -105 then flag = 1;
    output;
    end;
run;

proc print data=want noobs; var id variable1 flag; run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;PRE&gt;                              id    variable1    flag

                               1          1        0
                               1          2        0
                               1       -200        1
                               1          3        1
                               2          1        0
                               2          2        0
                               2       -200        1
                               2          3        1
                               3          1        0
                               3          2        0
                               3       -200        1
                               3          3        1
&lt;/PRE&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:39:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534546#M146688</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2019-02-11T17:39:14Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534547#M146689</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13879"&gt;@Reeza&lt;/a&gt;&amp;nbsp;:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Regarding your caveat&amp;nbsp;"LAG() functions don't work in conditional statements so you need to pull it out of the conditional IF and calculate it regardless".&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I know that this advice is meant to correct the naïve understanding that LAG is a lookback, (rather than&amp;nbsp;a queue-update, which is what it really is).&amp;nbsp;&amp;nbsp; But&amp;nbsp;IMO "don't work" is a little overstated, for a couple of reasons:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;&lt;STRONG&gt;if-clause vs then-clause:&lt;/STRONG&gt;&lt;/EM&gt;&amp;nbsp; First, while using lag functions in the &lt;EM&gt;&lt;STRONG&gt;then-clause&lt;/STRONG&gt;&lt;/EM&gt; of an IF ... THEN statement can be counterintuitive, using them in the &lt;EM&gt;&lt;STRONG&gt;if-clause&lt;/STRONG&gt;&lt;/EM&gt; (even a compound if-clause) does not present any unexpected behavior.&amp;nbsp; I have tested (and I recall a discussion by &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/4"&gt;@ChrisHemedinger&lt;/a&gt;&amp;nbsp;on the subject), and have always found that every component of a compound if-condition&amp;nbsp;is evaluated, even if logically unnecessary (i.e.&amp;nbsp;when A=1&amp;nbsp;then&amp;nbsp;testing "IF A=1 or B=1"&amp;nbsp;theoretically doesn't need to evaluate B=1).&amp;nbsp; So "if A&amp;nbsp; or lag(b)=x" always updates the lag(b) queue, regardless of whether A is true.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;&lt;STRONG&gt;Sometimes you want conditional execution of lags:&lt;/STRONG&gt;&lt;/EM&gt;&amp;nbsp; There are times when putting a lag in the then-clause does make sense.&amp;nbsp; I have a paper &lt;A href="http://analytics.ncsu.edu/sesug/2017/SESUG2017_Paper-175_Final_PDF.pdf" target="_self"&gt;Leads and Lags: Static and Dynamic Queues in the SAS DATA Step, 2nd ed.&lt;/A&gt;&amp;nbsp;that shows some of them (in the "irregular interleaved series" section).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also, I recommend embedding the lag function inside an IFN or IFC function.&amp;nbsp; This will unconditionally execute the lag function, but only conditionally return the lag value.&amp;nbsp; For instance if sashelp.stocks were sorted by stock/date,&amp;nbsp; (it's actually stock/descending date), then calculating a monthly return (current CLOSE vs lagged CLOSE) that avoids contaminating one stock with the lagged value of the prior stock could be done as follows in a single statement:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sort data=sashelp.stocks out=sorted_stocks;
  by stock date;
run;

data want;
  set sorted_stocks;
  by stock;
  monthly_return=ifn(first.stock,.,(close-lag(close))/lag(close));
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But really we should probably "blame" SAS, which affixed the name "lag" to this function.&amp;nbsp; I suspect that if it were named something like "UPDATE_FIFOQ(x)" there would be much less confusion about its behavior in a conditional statement.&lt;/P&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:39:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534547#M146689</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2019-02-11T17:39:43Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534549#M146691</link>
      <description>&lt;P&gt;OK, adding an OUTPUT statement should fix that:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE class=" language-sas"&gt;&lt;CODE class="  language-sas"&gt;&lt;SPAN class="token procnames"&gt;data&lt;/SPAN&gt; want&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="token keyword"&gt;set&lt;/SPAN&gt; have&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="token statement"&gt;by&lt;/SPAN&gt; &lt;SPAN class="token keyword"&gt;id&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="token keyword"&gt;if&lt;/SPAN&gt; &lt;SPAN class="token function"&gt;first&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token keyword"&gt;id&lt;/SPAN&gt; &lt;SPAN class="token keyword"&gt;then&lt;/SPAN&gt; flag&lt;SPAN class="token operator"&gt;=&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;BR /&gt;&lt;/SPAN&gt;output;
&lt;SPAN class="token keyword"&gt;if&lt;/SPAN&gt; variable1 &lt;SPAN class="token operator"&gt;&amp;lt;&lt;/SPAN&gt; &lt;SPAN class="token number"&gt;-105&lt;/SPAN&gt; &lt;SPAN class="token keyword"&gt;then&lt;/SPAN&gt; flag&lt;SPAN class="token operator"&gt;=&lt;/SPAN&gt;&lt;SPAN class="token number"&gt;1&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="token keyword"&gt;retain&lt;/SPAN&gt; flag&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="token procnames"&gt;run&lt;/SPAN&gt;&lt;SPAN class="token punctuation"&gt;;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:44:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534549#M146691</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2019-02-11T17:44:20Z</dc:date>
    </item>
    <item>
      <title>Re: How to use LAG function in an iterative way?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534550#M146692</link>
      <description>&lt;P&gt;Or if you want to avoid an explicit output statement, the lag function is uniquely useful:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  set have;
  by id;
  retain flag;
  if lag(variable1)&amp;lt;=-105 then flag=1;
  if first.id then flag=.;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 11 Feb 2019 17:51:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-use-LAG-function-in-an-iterative-way/m-p/534550#M146692</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2019-02-11T17:51:03Z</dc:date>
    </item>
  </channel>
</rss>

