<?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: Do Loop within group optimization question in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160869#M263319</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I think I will add a new variable for the last record of each object to control for the LOOP.&lt;/P&gt;&lt;P&gt;data have; set have;&lt;BR /&gt;by object;&lt;BR /&gt;if last.object then last=1;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want (keep=object time price level greater);&lt;BR /&gt;&amp;nbsp; set have nobs=totalobs;&lt;/P&gt;&lt;P&gt;&amp;nbsp; i+1;&lt;BR /&gt;&amp;nbsp; found=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do j=i+1 to totalobs until (found=1&lt;SPAN style="text-decoration: underline;"&gt; or last=1&lt;/SPAN&gt;) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have(keep=object time price rename=(object =obj time=greater price=price2)) point=j;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if price2 &amp;gt; level and obj=object then found=1;&lt;BR /&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if found=0 then greater=0;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Tue, 23 Dec 2014 20:23:27 GMT</pubDate>
    <dc:creator>hhchenfx</dc:creator>
    <dc:date>2014-12-23T20:23:27Z</dc:date>
    <item>
      <title>Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160865#M263315</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Everyone,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My problem is that for each record, I want to find the future "time" when future price&amp;gt; current record level.&lt;/P&gt;&lt;P&gt;Since the data has many different object, I want to apply the above rule for each object time series.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; the condition is: if price2 &amp;gt; level and &lt;SPAN style="text-decoration: underline;"&gt;obj=object&lt;/SPAN&gt; then found=1;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My code below can handle it. But what I worry is that SAS will go from current record to THE END of FILE if there is no future record that meet the condition Price&amp;gt;current level.&lt;/P&gt;&lt;P&gt;It will be very much inefficient since it only need to check record of the same object.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I wonder if the sort step will help SAS to process more efficiently, meaning when object change, SAS will stop checking but assign grater=0 (meaning condition is not met).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If this sort step doesnt help, is there any way to make it process better?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thank you,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;HHC&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input object time price level;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;1 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/P&gt;&lt;P&gt;1 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/P&gt;&lt;P&gt;1 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/P&gt;&lt;P&gt;1 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 25&lt;/P&gt;&lt;P&gt;1 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp; 63&lt;/P&gt;&lt;P&gt;2 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29&lt;/P&gt;&lt;P&gt;2 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/P&gt;&lt;P&gt;2 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&lt;/P&gt;&lt;P&gt;2 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&lt;/P&gt;&lt;P&gt;2 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/P&gt;&lt;P&gt;3 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29&lt;/P&gt;&lt;P&gt;3 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 22&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32&lt;/P&gt;&lt;P&gt;3 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 52&lt;/P&gt;&lt;P&gt;3 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&amp;nbsp;&amp;nbsp;&amp;nbsp; 50&lt;/P&gt;&lt;P&gt;3 100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1200&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/P&gt;&lt;P&gt;;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc sort; by object time;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data want (keep=object time price level greater);&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have nobs=totalobs;&lt;/P&gt;&lt;P&gt;&amp;nbsp; i+1;&lt;/P&gt;&lt;P&gt;&amp;nbsp; found=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do j=i+1 to totalobs until (found=1) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have(keep=object time price rename=(object =obj time=greater price=price2)) point=j;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if price2 &amp;gt; level and obj=object then found=1;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if found=0 then greater=0;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 23 Dec 2014 05:13:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160865#M263315</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2014-12-23T05:13:29Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160866#M263316</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;How big table you have ?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE&gt; 
 
data have;
&amp;nbsp; input object time price level;
&amp;nbsp; datalines;
1 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9
1 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3
1 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5
1 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 25
1 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp; 63
2 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29
2 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3
2 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15
2 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 15
2 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp; 6
3 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29
3 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 22&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32
3 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 52
3 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&amp;nbsp;&amp;nbsp;&amp;nbsp; 50
3 100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1200&amp;nbsp;&amp;nbsp;&amp;nbsp; 6
;run;
 
 proc sql;
&amp;nbsp; create table want as
&amp;nbsp;&amp;nbsp; select *,case when (select count(*) from have where object=a.object and time gt a.time and price gt a.level) gt 0 then 1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else 0 end as found
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from have as a;
quit;
&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Xia Keshan&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 23 Dec 2014 06:08:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160866#M263316</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2014-12-23T06:08:45Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160867#M263317</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks for helping.&lt;/P&gt;&lt;P&gt;The file is more than 20 GB (of course I can break it into pieces).&lt;/P&gt;&lt;P&gt;Also, I really wonder how SAS process the DO LOOP code.&lt;/P&gt;&lt;P&gt;HHC&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 23 Dec 2014 16:54:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160867#M263317</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2014-12-23T16:54:17Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160868#M263318</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I think the poblem is not the DO LOOP but the SET with point=&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;CTorres&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 23 Dec 2014 17:58:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160868#M263318</guid>
      <dc:creator>CTorres</dc:creator>
      <dc:date>2014-12-23T17:58:52Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160869#M263319</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I think I will add a new variable for the last record of each object to control for the LOOP.&lt;/P&gt;&lt;P&gt;data have; set have;&lt;BR /&gt;by object;&lt;BR /&gt;if last.object then last=1;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want (keep=object time price level greater);&lt;BR /&gt;&amp;nbsp; set have nobs=totalobs;&lt;/P&gt;&lt;P&gt;&amp;nbsp; i+1;&lt;BR /&gt;&amp;nbsp; found=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do j=i+1 to totalobs until (found=1&lt;SPAN style="text-decoration: underline;"&gt; or last=1&lt;/SPAN&gt;) ;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have(keep=object time price rename=(object =obj time=greater price=price2)) point=j;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if price2 &amp;gt; level and obj=object then found=1;&lt;BR /&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if found=0 then greater=0;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 23 Dec 2014 20:23:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160869#M263319</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2014-12-23T20:23:27Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160870#M263320</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;How big is the data set with columns "object, time &amp;amp; price" only? Reason I'm asking: If this would fit into memory then we could use quite a simple and well performing approach using a SAS hash table.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 24 Dec 2014 02:46:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160870#M263320</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2014-12-24T02:46:01Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160871#M263321</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Two proposed solutions, the first one being the faster one:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;For solution 1, I assume that for a given object, there will be no more than 10000 records. Of course one can rewrite solution 1 with hash objects replacing the arrays. I am doing this on the fly and doing quick and dirty.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/********************/&lt;BR /&gt;/**** solution 1 ****/&lt;BR /&gt;/********************/&lt;BR /&gt;data want(keep=object time price level greater);&lt;BR /&gt;&amp;nbsp; array prc(10000) _temporary_;&lt;BR /&gt;&amp;nbsp; array tim(10000) _temporary_;&lt;BR /&gt;&amp;nbsp; nn=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; call missing (of prc(*));&lt;BR /&gt;&amp;nbsp; call missing (of tim(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (last.object);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; by object;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nn+1;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; prc(nn)=price;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; tim(nn)=time;&lt;BR /&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ntot=nn;&lt;BR /&gt;&amp;nbsp; nn=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (last.object);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; by object;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nn+1;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; greater=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i=nn+1 to ntot;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (prc(i)&amp;gt;level) then do; greater=tim(i); leave; end;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;BR /&gt;&amp;nbsp; end;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/********************/&lt;BR /&gt;/**** solution 2 ****/&lt;BR /&gt;/********************/&lt;BR /&gt;proc sql;&lt;BR /&gt;create table want as&lt;BR /&gt;select a.*, coalesce(&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (select time &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from&amp;nbsp;&amp;nbsp; have &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where&amp;nbsp; object=a.object and time gt a.time and price gt a.level&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; having time = min(time)),0) as greater&lt;BR /&gt;from have a;&lt;BR /&gt;quit;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;The issue, as stated by hhchenfx, is the issue of the performance of a solution given a very large dataset.&lt;/P&gt;&lt;P&gt;I recalled reading a SUGI paper showing that sorting using hash object is faster than the plain proc sort when the SAS datasets are quite large; but then the hash object method uses a lot of RAM. Proc SQL is often as fast as hash object methods and uses as much resources. For the hash object and SQL methods, the dataset needs not be sorted beforehand.&amp;nbsp; Also the point= statement is pretty slow. If your system does not have lots of RAM, SQL solutions can be slow.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I made a simulated dataset:&lt;/P&gt;&lt;P&gt;/***************************/&lt;BR /&gt;/**** simulated dataset ****/&lt;BR /&gt;/***************************/&lt;BR /&gt;data have(drop=t);&lt;BR /&gt;&amp;nbsp; do object=1 to 10000;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; time=1;&lt;BR /&gt;&amp;nbsp; do t = 1 to 300;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; time+(1+ceil(4*ranuni(3)));&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; price = ceil(200*ranuni(3));&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; level = price+ceil(30*ranuni(3));&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;BR /&gt;&amp;nbsp; end;&lt;BR /&gt;&amp;nbsp; end;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;This table is 158 MB in size and has 3,000,000 rows. My SAS system does not have plentiful resources.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;SAS Log for solution 1 (run 1): real time 3.42 seconds cpu time&amp;nbsp; 3.37 seconds.&lt;/P&gt;&lt;P&gt;SAS Log for solution 1 (run 2): real time 3.52 seconds cpu time&amp;nbsp; 3.50 seconds.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With the method of hhchenfx, I had to add code such as:&lt;BR /&gt;&lt;STRONG&gt;if (i&amp;gt;= 300) then stop;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;SAS Log for method of hhchenfx :&amp;nbsp; 30 obs -&amp;gt; real time 10.18 seconds&amp;nbsp;&amp;nbsp; cpu time&amp;nbsp; 10.19 seconds&lt;BR /&gt;SAS Log for method of hhchenfx : 300 obs -&amp;gt; real time 2:22.43 minutes cpu time&amp;nbsp; 2:22.48 minutes&lt;/P&gt;&lt;P&gt;or other words just to find variable greater for the first 300 records for table have, it took seconds 140. The simulated dataset has 3,000,000 records.&lt;BR /&gt;It would have taken some 140*(3000000/300)*(1/2) = 710000 sec = 197 hours.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;For solution 2, I had to modify code from&lt;BR /&gt;&lt;STRONG&gt;from have a;&lt;/STRONG&gt;&lt;BR /&gt;to:&lt;BR /&gt;&lt;STRONG&gt;from have (obs=30) a;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;SAS Log for solution 2 ( 30 records) :&amp;nbsp; real time&amp;nbsp;&amp;nbsp; 10.96 seconds cpu time&amp;nbsp;&amp;nbsp;&amp;nbsp; 10.97 seconds&lt;BR /&gt;SAS Log for solution 2 (300 records) :&amp;nbsp; real time 1:48.74 minutes cpu time&amp;nbsp; 1:48.78 minutes&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 24 Dec 2014 23:36:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160871#M263321</guid>
      <dc:creator>billfish</dc:creator>
      <dc:date>2014-12-24T23:36:05Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160872#M263322</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I believe using a hash approach could be very efficient. Easiest would be if you can fit all the data required for look-up into a single hash at once. If this is not possible then you would need to process your data object group by object group. Still possible using a hash but less efficient. Below the code for both approaches.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input object time price level;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;1 1 5 9&lt;/P&gt;&lt;P&gt;1 2 2 3&lt;/P&gt;&lt;P&gt;1 3 8 5&lt;/P&gt;&lt;P&gt;1 4 10 25&lt;/P&gt;&lt;P&gt;1 5 12 63&lt;/P&gt;&lt;P&gt;2 1 15 29&lt;/P&gt;&lt;P&gt;2 2 12 3&lt;/P&gt;&lt;P&gt;2 3 18 15&lt;/P&gt;&lt;P&gt;2 4 10 15&lt;/P&gt;&lt;P&gt;2 5 18 6&lt;/P&gt;&lt;P&gt;3 1 15 29&lt;/P&gt;&lt;P&gt;3 2 22 32&lt;/P&gt;&lt;P&gt;3 3 8 52&lt;/P&gt;&lt;P&gt;3 4 11 50&lt;/P&gt;&lt;P&gt;3 100 1200 6&lt;/P&gt;&lt;P&gt;;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;/* approach 1: All look-up data fits into a single hash */&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;data want;&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if _n_=1 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if 0 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have(keep=object time price rename=(object=_object time=future_time price=future_price));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hash h1(dataset:'have(keep=object time price rename=(object=_object time=future_time price=future_price))',ordered:'yes');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineKey('_object','future_time');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineData(all:'yes');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineDone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hiter iter('h1');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; found=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; _rc= iter.setcur(key:object, key:time);&lt;/P&gt;&lt;P&gt;&amp;nbsp; _rc = iter.next();&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do while (_rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if _object ne object then leave;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if future_price &amp;gt; level then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; found=1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; leave;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc = iter.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if found =0 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call missing (future_time, future_price);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;/* approach 2: Processing per object group using hash look-up */&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;proc sort data=have out=inter;&lt;/P&gt;&lt;P&gt;&amp;nbsp; by object;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data want;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; set inter;&lt;/P&gt;&lt;P&gt;&amp;nbsp; by object;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if _n_=1 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if 0 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set inter(keep=object time price rename=(time=future_time price=future_price));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hash h1(ordered:'yes');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineKey('object','future_time');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineData('future_time','future_price');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.defineDone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hiter iter('h1');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if first.object then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.clear();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do until(last.object);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&amp;nbsp; inter(keep=object time price rename=(time=future_time price=future_price));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; by object;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc=h1.add();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; found=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; _rc= iter.setcur(key:object, key:time);&lt;/P&gt;&lt;P&gt;&amp;nbsp; _rc = iter.next();&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do while (_rc = 0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if future_price &amp;gt; level then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; found=1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; leave;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc = iter.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if found =0 then&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call missing (future_time, future_price);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Dec 2014 01:59:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160872#M263322</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2014-12-25T01:59:27Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160873#M263323</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Of course, If table has already been sorted,&amp;nbsp; DOW + temporary array is the fastest solution . But if not I recommend to split this big table into lots of small table .&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Xia Keshan&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Dec 2014 06:15:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160873#M263323</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2014-12-25T06:15:20Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160874#M263324</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Everyone,&lt;/P&gt;&lt;P&gt;The discussion here really helps me a lot.&lt;/P&gt;&lt;P&gt;I am new to Hash process so I will not have any question here. Based on the simulated data, I find the array approach is so efficient.&lt;/P&gt;&lt;P&gt;I would like to make myself clear about it and below, I try to teach myself with explanation of each step.&lt;/P&gt;&lt;P&gt;I have 3 questions and it would be very much helpful if you could help me to clarify them.&lt;/P&gt;&lt;P&gt;Thank you so much and have a nice Holiday.&lt;/P&gt;&lt;P&gt;HHC&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;**********************************************************************************&lt;/P&gt;&lt;P&gt;*My 1st question is the how SAS process the code:&lt;/P&gt;&lt;P&gt;1. at the benning, SAS goes to section 2 and collect prc and time record from 1 to min(10,000 , last.object)&lt;/P&gt;&lt;P&gt;2. then SAS goes to Section 3, take the first record of have and run the checking with the array price();&lt;/P&gt;&lt;P&gt;*Once is done, SAS redo the 2 section with 2nd record of have&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I wonder why SAS doesn't run the section 1 from the beginning to the end before moving onto section 3.&lt;/P&gt;&lt;P&gt;What line of code prevent SAS from doing so?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;*My 2nd question is after finishing 1 record of have, why don’t we reset nn=0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;nn=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;*My erd question is: what is the role of :;&lt;/P&gt;&lt;P&gt;&amp;nbsp; call missing (of prc(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp; call missing (of tim(*));&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;***************************************************************************************************;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data want(keep=object time price level greater exit_prc);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="text-decoration: underline;"&gt;*Section 1&lt;/STRONG&gt;: declare array specification;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array prc(10000) _temporary_;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array tim(10000) _temporary_;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; kk=0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; call missing (of prc(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp; call missing (of tim(*));&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="text-decoration: underline;"&gt;&lt;STRONG&gt;*Section 2:&lt;/STRONG&gt;&lt;/SPAN&gt; gathering records in the array prc() and tim(). &lt;/P&gt;&lt;P&gt;These array is Max 10,000 records;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (last.object);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; by object;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; kk+1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; prc(kk)=price;&amp;nbsp;&amp;nbsp;&amp;nbsp; *start from price(0+1)?;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; tim(kk)=time;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="text-decoration: underline;"&gt;&lt;STRONG&gt;*Section 3&lt;/STRONG&gt;&lt;/SPAN&gt;: the main code of checking first record with price above level;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ntot=kk;&amp;nbsp;&amp;nbsp;&amp;nbsp; *the ntot is the value of record in the prc()/tim() array, Max 10,000;&lt;/P&gt;&lt;P&gt;&amp;nbsp; nn=0;&amp;nbsp;&amp;nbsp;&amp;nbsp; *Reset nn=0 for below do loop;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (last.object);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have;&amp;nbsp;&amp;nbsp;&amp;nbsp; *open file have, start with the first record;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; by object;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nn+1;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *start with nn=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; greater=0;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i=nn+1 to ntot; *first I value =1 to the max ntot record above, max 10,000;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (prc(i)&amp;gt;level) then do; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; greater=tim(i);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit_prc=prc(i); &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; leave; *exit the checking loop to OUTPUT; &lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Dec 2014 19:19:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160874#M263324</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2014-12-26T19:19:26Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160875#M263325</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;*My 1st question is the how SAS process the code:&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;1. at the benning, SAS goes to section 2 and collect prc and time record from 1 to min(10,000 , last.object)&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;2. then SAS goes to Section 3, take the first record of have and run the checking with the array price();&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;*Once is done, SAS redo the 2 section with 2nd record of have&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;I wonder why SAS doesn't run the section 1 from the beginning to the end before moving onto section 3.&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;What line of code prevent SAS from doing so?&lt;/P&gt;






&lt;/PRE&gt;&lt;P&gt;The first DO UNTIL(LAST.OBJECT) loop will cause SAS to read the KK records for current OBJECT group.&amp;nbsp; This happens all in one execution of the main data step loop.&amp;nbsp; The LAST.OBJECT automatic variable will be set to true when you have read the last observation in this group in the first SET statement.&amp;nbsp; Note that the second loop works the same way but it is reading the data set again because you have another SET statement. So it will read the same set of observations again starting with the first one for the current BY group. So the normal data step loop will actually run only once per BY group rather than the normal once per observation.&amp;nbsp; This happens because you have nested the SET statements inside of DO loops so that they could execute more than once per execution of the main data step loop and so process more than one observation in each execution of the main data step loop.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;*My 2nd question is after finishing 1 record of have, why don’t we reset nn=0;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;nn=0;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&amp;nbsp; end;&lt;/P&gt;






&lt;/PRE&gt;&lt;P&gt;You would not want to reset NN here as NN is working as your record counter within this BY group.&amp;nbsp; You are using it to set the lower bound of the DO loop that does the look ahead to find the first occurrence where the target price is met.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;*My erd question is: what is the role of :;&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&amp;nbsp; call missing (of prc(*));&lt;/P&gt;
&lt;P style="font-family: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; background-color: #ffffff;"&gt;&amp;nbsp; call missing (of tim(*));&lt;/P&gt;






&lt;/PRE&gt;&lt;P&gt;You actually do not need these lines in the code you posted.&amp;nbsp; Note that TEMPORARY arrays are automatically retained so CALL MISSING() is a good way to reset them all to missing.&amp;nbsp; But since section 2 is setting values of all of the values in this particular group there is no need to set the other values to missing (or anything else).&amp;nbsp; The second loop in section 3 will only reference the array elements that had values assigned in the first do loop in section 2.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Dec 2014 20:40:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160875#M263325</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2014-12-26T20:40:23Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160876#M263326</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thank you all for your help.&lt;/P&gt;&lt;P&gt;HHC&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 27 Dec 2014 05:03:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160876#M263326</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2014-12-27T05:03:22Z</dc:date>
    </item>
    <item>
      <title>Re: Do Loop within group optimization question</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160877#M263327</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I try to do the moving Highest and Lowest of price using this array approach.&lt;/P&gt;&lt;P&gt;Somehow I got the error "Array subscript out of range ..."&lt;/P&gt;&lt;P&gt;Could you help me to correct it?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thank you,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;HHC &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input object time price level;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;1 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&lt;/P&gt;&lt;P&gt;1 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/P&gt;&lt;P&gt;1 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/P&gt;&lt;P&gt;1 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 25&lt;/P&gt;&lt;P&gt;1 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp; 63&lt;/P&gt;&lt;P&gt;2 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29&lt;/P&gt;&lt;P&gt;2 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/P&gt;&lt;P&gt;2 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&lt;/P&gt;&lt;P&gt;2 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&lt;/P&gt;&lt;P&gt;2 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/P&gt;&lt;P&gt;3 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 29&lt;/P&gt;&lt;P&gt;3 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 22&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32&lt;/P&gt;&lt;P&gt;3 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 52&lt;/P&gt;&lt;P&gt;3 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&amp;nbsp;&amp;nbsp;&amp;nbsp; 50&lt;/P&gt;&lt;P&gt;3 100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1200&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/P&gt;&lt;P&gt;;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want2;&lt;BR /&gt;array price2(4) _temporary_;&lt;/P&gt;&lt;P&gt;kk=0;&lt;/P&gt;&lt;P&gt;do until (last.object);&lt;BR /&gt; set have;&lt;BR /&gt; by object;&lt;BR /&gt; kk+1;&lt;BR /&gt; price2(kk)=price;&lt;BR /&gt;end;&lt;/P&gt;&lt;P&gt;max_record=kk;&lt;BR /&gt;nn=0;&lt;/P&gt;&lt;P&gt;do until (last.object);&lt;BR /&gt; set have;&lt;BR /&gt; by object;&lt;BR /&gt; nn+1;&lt;BR /&gt; highest=0;&lt;BR /&gt; lowest=10000;&lt;/P&gt;&lt;P&gt; do i=nn+1 to max_record;&lt;BR /&gt;&amp;nbsp; if price2(i)&amp;gt;highest then highest=price2(i);&lt;BR /&gt;&amp;nbsp; if price2(i)&amp;lt;lowest then lowest=price2(i);&lt;BR /&gt; end;&lt;BR /&gt;end;&lt;BR /&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 02 Jan 2015 13:44:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Do-Loop-within-group-optimization-question/m-p/160877#M263327</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2015-01-02T13:44:01Z</dc:date>
    </item>
  </channel>
</rss>

