<?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 does this work? Weird DO loop. in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834029#M329735</link>
    <description>&lt;P&gt;The hard part is to decide what qualifies as esoteric.&amp;nbsp; To some, the DOW loop itself is esoteric.&amp;nbsp; Hashing may be seen&amp;nbsp; as esoteric.&amp;nbsp; Perhaps regular expressions...&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;While I personally don't write code that hijacks _n_, that's partly because I don't work with data where the efficiency gain of avoiding introducing a single variable into the PDV would be valuable to me.&amp;nbsp; But I don't see the inherited code as unreasonable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sun, 18 Sep 2022 16:26:09 GMT</pubDate>
    <dc:creator>Quentin</dc:creator>
    <dc:date>2022-09-18T16:26:09Z</dc:date>
    <item>
      <title>How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833976#M329716</link>
      <description>Hello, SAS Gurus!&lt;BR /&gt;&lt;BR /&gt;Could you please help me?&lt;BR /&gt;First, I couldn’t understand what this (given, not mine) piece of code accomplishes. I got an explanation that the goal was to delete previous observations of time series until the beginning of the series for that case_nbr. Let’s say, we are talking about 2022, January to September. The variable reason can be either a character, like “P” or “22” or blank. We do not like blanks and try to find the original reason as of January 2022. If it’s not there, we’d rather start the series with the first record of non-blank reason, even if that’s August 2022.&lt;BR /&gt;&lt;BR /&gt;/* I am not sure what this thing does... */&lt;BR /&gt;data want ;&lt;BR /&gt;do _n_= 0 by 0 until(last.case_nbr) ;&lt;BR /&gt;set W ;&lt;BR /&gt;by case_nbr ;&lt;BR /&gt;if reason ne '' then _n_ = 1 ;&lt;BR /&gt;if _n_ then output ;&lt;BR /&gt;end;&lt;BR /&gt;run;&lt;BR /&gt;&lt;BR /&gt;I have seen and used:&lt;BR /&gt;If first.var&lt;BR /&gt;If last.var&lt;BR /&gt;Do while&lt;BR /&gt;Do until&lt;BR /&gt;Do _n_ = 1 by 1 until(eof)&lt;BR /&gt;and so on. But never do _n_= 0 by 0 until(last.var ) ;</description>
      <pubDate>Sat, 17 Sep 2022 13:17:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833976#M329716</guid>
      <dc:creator>StacieOsborne</dc:creator>
      <dc:date>2022-09-17T13:17:58Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833978#M329717</link>
      <description>&lt;P&gt;The code reuses the automatic variable _N_ as a logical flag (one does not need to drop automatic variables).&lt;/P&gt;
&lt;P&gt;Since there is no increment (BY 0), the variable stays at 0 throughout the loop, until a non-missing REASON is encountered. The loop terminates with last.case_nbr.&lt;/P&gt;
&lt;P&gt;After the loop, the(Boolean) value is used to control the output.&lt;/P&gt;</description>
      <pubDate>Sat, 17 Sep 2022 13:48:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833978#M329717</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-09-17T13:48:03Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833980#M329719</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks for posting the full code here.&amp;nbsp; Much easier to discuss here than on LinkedIn, and more folks to join in the fun.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This is an interesting use of the DOW-loop construct.&amp;nbsp; This is an unofficial name for explicitly looping over a SET statement, often in by groups.&amp;nbsp; Paul Dorfman wrote a classic paper on DOW-loop:&amp;nbsp;&lt;A href="https://www.lexjansen.com/nesug/nesug08/hw/hw02.pdf" target="_blank"&gt;https://www.lexjansen.com/nesug/nesug08/hw/hw02.pdf&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;At the top of the the DOW-loop, they set _N_ to 0, and tell the DOW loop to keep looping until it has read the last record for a case_nbr.&amp;nbsp; And they use BY 0 because they don't want the loop iteration to increment _N_.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Inside the loop it reads each record within the case_nbr.&amp;nbsp; If it finds a record with a record where REASON is not missing, it sets _N_=1.&amp;nbsp; So _N_ is being used as a yes/no flag that means "I have found a record with non-missing reason for this case_nbr".&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;At the bottom of the loop, if _N_=1, it outputs the record.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The end result of this logic is that for each case_nbr, it will start outputting records when it finds the first record with non-missing REASON.&amp;nbsp; That's hard for me to say in words, here's some example data and code, and I added a PUT statement to your code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have ;
  input case_nbr recno reason $3. ;
  cards ;
1 1    
1 2    
1 3 foo
1 4    
2 1 foo
2 2    
2 3    
2 4    
3 1    
3 2    
3 3    
3 4 foo
4 1    
4 2    
4 3    
4 4    
;
run ;


data want ;
  do _n_= 0 by 0 until(last.case_nbr) ;
    set have ;
    by case_nbr ;
    if reason ne '' then _n_ = 1 ;
    put (case_nbr recno reason _n_)(=) ;
    if _n_ then output ;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The log is:&lt;/P&gt;
&lt;PRE&gt;24   data want ;
25     do _n_= 0 by 0 until(last.case_nbr) ;
26       set have ;
27       by case_nbr ;
28       if reason ne '' then _n_ = 1 ;
29       put (case_nbr recno reason _n_)(=) ;
30       if _n_ then output ;
31     end;
32   run;

case_nbr=1 recno=1 reason=  _N_=0
case_nbr=1 recno=2 reason=  _N_=0
case_nbr=1 recno=3 reason=foo _N_=1
case_nbr=1 recno=4 reason=  _N_=1
case_nbr=2 recno=1 reason=foo _N_=1
case_nbr=2 recno=2 reason=  _N_=1
case_nbr=2 recno=3 reason=  _N_=1
case_nbr=2 recno=4 reason=  _N_=1
case_nbr=3 recno=1 reason=  _N_=0
case_nbr=3 recno=2 reason=  _N_=0
case_nbr=3 recno=3 reason=  _N_=0
case_nbr=3 recno=4 reason=foo _N_=1
case_nbr=4 recno=1 reason=  _N_=0
case_nbr=4 recno=2 reason=  _N_=0
case_nbr=4 recno=3 reason=  _N_=0
case_nbr=4 recno=4 reason=  _N_=0
NOTE: There were 16 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 7 observations and 3 variables.
&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you look at _N_, you can see Case 1 will have records 3 and 4 output, because the first non-missing REASON is record 3.&amp;nbsp; Case 2 has all records output.&amp;nbsp; Case 3 has only its last record output. Case 4 will have no records output, because all records have a missing reason.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you were doing this without a DOW-loop approach, you might use BY group processing and set a retained flag to select records, e.g.:&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 case_nbr ;
  retain flag ;
  if first.case_nbr then flag=0 ;
  if reason ne '' then flag=1 ;
  if flag=1 ;
run ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;HTH!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 17 Sep 2022 13:56:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833980#M329719</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2022-09-17T13:56:00Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833982#M329721</link>
      <description>I see I did not realize that the OUTPUT was part of the loop. So it writes all observations for a group after the first non-missing value is encountered.&lt;BR /&gt;Please use proper indentation in your code, and post it into a window opened with the „little running man“ button.&lt;BR /&gt;Spaghetti code will always get people in trouble.</description>
      <pubDate>Sat, 17 Sep 2022 14:39:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833982#M329721</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-09-17T14:39:35Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833985#M329722</link>
      <description>&lt;P&gt;Using tricks is fun but can be obfuscating...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Easier to see what this thing does... */
data want ;
do until(last.case_nbr) ;
	set W ; by case_nbr ;
	if not missing(reason) then started = 1 ;
	if started then output ;
	end ;
drop started ;
run ;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 17 Sep 2022 18:12:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/833985#M329722</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2022-09-17T18:12:12Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834006#M329728</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/462"&gt;@PGStats&lt;/a&gt; - Exactly. If you work in a team who is maintaining a suite of SAS applications then you should always (try to) use coding techniques that are obvious and easy to understand by others with less SAS experience. Just because you can code an esoteric method doesn't mean that you should. If you are coding just for yourself then that's fine, but not if you expect others to easily follow what you have done. &lt;/P&gt;</description>
      <pubDate>Sat, 17 Sep 2022 23:45:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834006#M329728</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-09-17T23:45:07Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834029#M329735</link>
      <description>&lt;P&gt;The hard part is to decide what qualifies as esoteric.&amp;nbsp; To some, the DOW loop itself is esoteric.&amp;nbsp; Hashing may be seen&amp;nbsp; as esoteric.&amp;nbsp; Perhaps regular expressions...&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;While I personally don't write code that hijacks _n_, that's partly because I don't work with data where the efficiency gain of avoiding introducing a single variable into the PDV would be valuable to me.&amp;nbsp; But I don't see the inherited code as unreasonable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 18 Sep 2022 16:26:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834029#M329735</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2022-09-18T16:26:09Z</dc:date>
    </item>
    <item>
      <title>Re: How does this work? Weird DO loop.</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834037#M329738</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/19879"&gt;@Quentin&lt;/a&gt;&amp;nbsp;-&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/462"&gt;@PGStats&lt;/a&gt;&amp;nbsp;'s version is reasonably acceptable in my view, the OPs's not so much&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; ...&lt;/P&gt;</description>
      <pubDate>Sun, 18 Sep 2022 20:01:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-does-this-work-Weird-DO-loop/m-p/834037#M329738</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-09-18T20:01:25Z</dc:date>
    </item>
  </channel>
</rss>

