<?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: PLZ: Macro Urgent Help in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51469#M10803</link>
    <description>If I've understand correctly your question and being the format solution a cleaner and simpler way of doing this, also consider the following alternative.&lt;BR /&gt;
&lt;BR /&gt;
proc sort data = one;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
data output;&lt;BR /&gt;
set one;&lt;BR /&gt;
retain _TPR . _C1 _C2; /* temporary vars for holding the maximum reg */&lt;BR /&gt;
drop _:;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
if _TPR lt TPR then do; &lt;BR /&gt;
_TPR=TPR; _C1=C1; _C2=C2; /* hold maximum reg */&lt;BR /&gt;
end;&lt;BR /&gt;
if last.FPR; /* if level end, output */&lt;BR /&gt;
TPR=_TPR; C1=_C1; C2=_C2;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
Anyway, there is no need for macro coding here.&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;.</description>
    <pubDate>Fri, 03 Jul 2009 09:20:44 GMT</pubDate>
    <dc:creator>DanielSantos</dc:creator>
    <dc:date>2009-07-03T09:20:44Z</dc:date>
    <item>
      <title>PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51462#M10796</link>
      <description>data one;&lt;BR /&gt;
input FPR c1 c2 TPR;&lt;BR /&gt;
cards; &lt;BR /&gt;
0.1 1.63223 1.63223 0.81557 &lt;BR /&gt;
0.2 1.25044 1.25044 0.91712 &lt;BR /&gt;
0.3 0.98085 0.98085 0.95858 &lt;BR /&gt;
0.4 0.75412 0.75412 0.97883 &lt;BR /&gt;
0.5 0.54504 0.54504 0.98940 &lt;BR /&gt;
0.6 0.33854 0.33854 0.99502 &lt;BR /&gt;
0.7 0.12029 0.12029 0.99793 &lt;BR /&gt;
0.8 -0.13165 -0.13165 0.99932 &lt;BR /&gt;
0.9 -0.47569 -0.47569 0.99988 &lt;BR /&gt;
1.0 -1.27726 -1.27726 1.00000 &lt;BR /&gt;
;&lt;BR /&gt;
proc means data=one max ;&lt;BR /&gt;
var TPR;&lt;BR /&gt;
output out=maxMTPR max=MTPR;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
I want to create one table contain data that has the maximum of TPR (MTPR) for every level of FPR that less than threshold, such that &lt;BR /&gt;
FPR &amp;lt;= 0.1&lt;BR /&gt;
FPR &amp;lt;= 0.2&lt;BR /&gt;
FPR &amp;lt;= 0.3&lt;BR /&gt;
FPR &amp;lt;= 0.4&lt;BR /&gt;
FPR &amp;lt;= 0.5&lt;BR /&gt;
FPR &amp;lt;= 0.6&lt;BR /&gt;
FPR &amp;lt;= 0.7&lt;BR /&gt;
FPR &amp;lt;= 0.8&lt;BR /&gt;
FPR &amp;lt;= 0.9&lt;BR /&gt;
FPR &amp;lt;= 1&lt;BR /&gt;
And every run output the c1, c2 correspond to the maximum of TPR (MTPR).  Can you provide me macro program to do this.&lt;BR /&gt;
Thank you for help</description>
      <pubDate>Thu, 02 Jul 2009 13:48:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51462#M10796</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-02T13:48:18Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51463#M10797</link>
      <description>, such that &lt;BR /&gt;
FPR &lt;BR /&gt;
&lt;BR /&gt;
FPR &amp;lt;= 0.1&lt;BR /&gt;
FPR &amp;lt;= 0.2&lt;BR /&gt;
FPR &amp;lt;= 0.3&lt;BR /&gt;
FPR &amp;lt;= 0.4&lt;BR /&gt;
FPR &amp;lt;= 0.5&lt;BR /&gt;
FPR &amp;lt;= 0.6&lt;BR /&gt;
FPR &amp;lt;= 0.7&lt;BR /&gt;
FPR &amp;lt;= 0.8&lt;BR /&gt;
FPR &amp;lt;= 0.9&lt;BR /&gt;
FPR &amp;lt;= 1&lt;BR /&gt;
And every run output the c1, c2 correspond to the maximum of TPR (MTPR).  Can you provide me macro program to do this.&lt;BR /&gt;
Thank you for help</description>
      <pubDate>Thu, 02 Jul 2009 13:50:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51463#M10797</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-02T13:50:31Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51464#M10798</link>
      <description>, such that &lt;BR /&gt;
FPR &lt;BR /&gt;
FPR LE 0.1&lt;BR /&gt;
FPR LE 0.2&lt;BR /&gt;
FPR LE 0.3&lt;BR /&gt;
FPR LE 0.4&lt;BR /&gt;
FPR LE 0.5&lt;BR /&gt;
FPR LE 0.6&lt;BR /&gt;
FPR LE 0.7&lt;BR /&gt;
FPR LE 0.8&lt;BR /&gt;
FPR LE 0.9&lt;BR /&gt;
FPR LE 1&lt;BR /&gt;
And every run output the c1, c2 correspond to the maximum of TPR (MTPR).  Can you provide me a macro program to do this.&lt;BR /&gt;
Thank you for help</description>
      <pubDate>Thu, 02 Jul 2009 14:00:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51464#M10798</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-02T14:00:13Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51465#M10799</link>
      <description>That a job for multilabel formats.&lt;BR /&gt;
[pre]&lt;BR /&gt;
proc format;&lt;BR /&gt;
  value lessthan (multilabel)&lt;BR /&gt;
    0-.1 = '&amp;lt;.1'&lt;BR /&gt;
    0-.2 = '&amp;lt;.2'&lt;BR /&gt;
    0-.3 = '&amp;lt;.3'&lt;BR /&gt;
    0-.4 = '&amp;lt;.4'&lt;BR /&gt;
    0-.5 = '&amp;lt;.5'&lt;BR /&gt;
    0-.6 = '&amp;lt;.6'&lt;BR /&gt;
    0-.7 = '&amp;lt;.7'&lt;BR /&gt;
    0-.8 = '&amp;lt;.8'&lt;BR /&gt;
    0-.9 = '&amp;lt;.9'&lt;BR /&gt;
    0-1  = '&amp;lt;1';&lt;BR /&gt;
run;&lt;BR /&gt;
proc means data=one max ;&lt;BR /&gt;
  class FPR;&lt;BR /&gt;
  var TPR;&lt;BR /&gt;
  output out=maxMTPR max=MTPR;&lt;BR /&gt;
  format TPR lessthan.;&lt;BR /&gt;
run;</description>
      <pubDate>Fri, 03 Jul 2009 01:12:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51465#M10799</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-03T01:12:34Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51466#M10800</link>
      <description>Is the size of a post limited now?&lt;BR /&gt;
&lt;BR /&gt;
You can then merge maxMTPR with the original table to get C1 and C2.</description>
      <pubDate>Fri, 03 Jul 2009 01:17:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51466#M10800</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-03T01:17:22Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51467#M10801</link>
      <description>Thank you Chris,&lt;BR /&gt;
&lt;BR /&gt;
The size of post fine, but am new here and this my first post.&lt;BR /&gt;
&lt;BR /&gt;
About the SAS code, I like your solution and for sure will be using it. But in case of large data with FPR take small increment (0.01, 0.02, 0.03,0.04,0.05...,0.10,……....,1) the use of format will be impractical. ANY HELP &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;</description>
      <pubDate>Fri, 03 Jul 2009 02:50:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51467#M10801</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-03T02:50:19Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51468#M10802</link>
      <description>The format will still be the easiest way in my opinion, even for thousands of buckets. In that case, generate the format automatically from a table using the CNTLIN= option. Don't forget to set the HLO variable to 'M'.</description>
      <pubDate>Fri, 03 Jul 2009 02:58:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51468#M10802</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-03T02:58:49Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51469#M10803</link>
      <description>If I've understand correctly your question and being the format solution a cleaner and simpler way of doing this, also consider the following alternative.&lt;BR /&gt;
&lt;BR /&gt;
proc sort data = one;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
data output;&lt;BR /&gt;
set one;&lt;BR /&gt;
retain _TPR . _C1 _C2; /* temporary vars for holding the maximum reg */&lt;BR /&gt;
drop _:;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
if _TPR lt TPR then do; &lt;BR /&gt;
_TPR=TPR; _C1=C1; _C2=C2; /* hold maximum reg */&lt;BR /&gt;
end;&lt;BR /&gt;
if last.FPR; /* if level end, output */&lt;BR /&gt;
TPR=_TPR; C1=_C1; C2=_C2;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
Anyway, there is no need for macro coding here.&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;.</description>
      <pubDate>Fri, 03 Jul 2009 09:20:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51469#M10803</guid>
      <dc:creator>DanielSantos</dc:creator>
      <dc:date>2009-07-03T09:20:44Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51470#M10804</link>
      <description>Indeed, sorting is also an option, though one that should be used after having considered the impact on resources, so I am always wary of recommending it.&lt;BR /&gt;
&lt;BR /&gt;
In this case, it might be a good idea as we can avoid a subsequent merge. Because we don't care about the full sorted table, I wouldn't create it, but create a view instead (to lower I/O). Also sorting can be used to find the second variable's maximum too.&lt;BR /&gt;
&lt;BR /&gt;
proc sql;&lt;BR /&gt;
create  view V as&lt;BR /&gt;
  select * from ONE &lt;BR /&gt;
  order by FPR, TPR;&lt;BR /&gt;
&lt;BR /&gt;
data OUTPUT;&lt;BR /&gt;
set V;&lt;BR /&gt;
by FPR;&lt;BR /&gt;
if last.FPR;&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
should do the job.</description>
      <pubDate>Sun, 05 Jul 2009 22:12:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51470#M10804</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-05T22:12:26Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51471#M10805</link>
      <description>Chris and Daniel Santos thank you both for your input and help. I decided to use the format program, it seems easy for me. Chris, I created sas file that has format of FPR from (0, 0-.01,0-0.02,0-.03,….,0-1), the question is can I load the format file using libname without opining the file. Let say the file in C:/format&lt;BR /&gt;
Thanks..</description>
      <pubDate>Sun, 05 Jul 2009 22:37:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51471#M10805</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-05T22:37:46Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51472#M10806</link>
      <description>Look up the FMTSEARCH option.</description>
      <pubDate>Sun, 05 Jul 2009 23:18:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51472#M10806</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-05T23:18:02Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51473#M10807</link>
      <description>Hello Chris.&lt;BR /&gt;
&lt;BR /&gt;
I agree with you, sorting is indeed resource consuming.&lt;BR /&gt;
Creating a view may reduce I/O at creation, but when solving it, the amount of I/O will be about the same or greater (since your sorting by two variables, and for what I've seen, SQL is so much more resource consuming when dealing with very large datasets).&lt;BR /&gt;
Sorting by FPR will suffice (and so, reduce I/O) , since the maximum TPR is easily obtained during the datasetp pass.&lt;BR /&gt;
&lt;BR /&gt;
Format is indeed a very good approach, and would be my choice also. But, should the values of C1 and C2 be the same of the row with the maximum TPR?&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;.</description>
      <pubDate>Mon, 06 Jul 2009 09:32:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51473#M10807</guid>
      <dc:creator>DanielSantos</dc:creator>
      <dc:date>2009-07-06T09:32:28Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51474#M10808</link>
      <description>Thank you Daniel, PROC means can be used to get maximum TPR; and c1 and c2 associated with the maximum TPR .&lt;BR /&gt;
&lt;BR /&gt;
maxid(TPR(c1))=c1,&lt;BR /&gt;
maxid(TPR(c2))=c2,</description>
      <pubDate>Mon, 06 Jul 2009 14:50:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51474#M10808</guid>
      <dc:creator>1234567</dc:creator>
      <dc:date>2009-07-06T14:50:27Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51475#M10809</link>
      <description>&amp;gt; Thank you Daniel, PROC means can be used to get&lt;BR /&gt;
&amp;gt; maximum TPR; and c1 and c2 associated with the&lt;BR /&gt;
&amp;gt; maximum TPR .&lt;BR /&gt;
&amp;gt; &lt;BR /&gt;
&amp;gt; maxid(TPR(c1))=c1,&lt;BR /&gt;
&amp;gt; maxid(TPR(c2))=c2,&lt;BR /&gt;
&lt;BR /&gt;
OK then, problem solved. Not part of the proc means above.&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;</description>
      <pubDate>Mon, 06 Jul 2009 16:10:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51475#M10809</guid>
      <dc:creator>DanielSantos</dc:creator>
      <dc:date>2009-07-06T16:10:37Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51476#M10810</link>
      <description>Good thinking!&lt;BR /&gt;
And I forgot the mlf option in my proc means, but you knew that.</description>
      <pubDate>Tue, 07 Jul 2009 01:21:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51476#M10810</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-07T01:21:39Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51477#M10811</link>
      <description>Daniel,&lt;BR /&gt;
Re. views, you've piqued my interest. I'll start a new thread.</description>
      <pubDate>Tue, 07 Jul 2009 22:09:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51477#M10811</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-07T22:09:31Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51478#M10812</link>
      <description>Probably not worth starting a new thread, though this is bit off-topic.&lt;BR /&gt;
&lt;BR /&gt;
I've conducted a few tests.&lt;BR /&gt;
&lt;BR /&gt;
[pre]data SASUSER.C;&lt;BR /&gt;
 do I=1 to 2e7; &lt;BR /&gt;
   A=ranuni(0);&lt;BR /&gt;
   B=round(A,.1);&lt;BR /&gt;
   C1=B; C2=B;&lt;BR /&gt;
   output;&lt;BR /&gt;
 end;&lt;BR /&gt;
run;&lt;BR /&gt;
 &lt;BR /&gt;
 &lt;BR /&gt;
%let s=%sysfunc(time());&lt;BR /&gt;
signon task1 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1 wait=no;&lt;BR /&gt;
  libname OUTLIB sasesock ":irc" timeout=5000;&lt;BR /&gt;
  proc sort data=SASUSER.C out=OUTLIB.C1;&lt;BR /&gt;
    by B A;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
rdisplay task1;&lt;BR /&gt;
signon task2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task2 wait=no;&lt;BR /&gt;
  libname INLIB sasesock ":irc" timeout=5000;&lt;BR /&gt;
  data D1;&lt;BR /&gt;
    set INLIB.C1;&lt;BR /&gt;
    by B;&lt;BR /&gt;
    if last.B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
rdisplay task2;&lt;BR /&gt;
waitfor task2;&lt;BR /&gt;
%put time=%sysevalf(%sysfunc(time())-&amp;amp;s); ***** MP CONNECT:  130s median time for 3 runs;&lt;BR /&gt;
 &lt;BR /&gt;
 &lt;BR /&gt;
proc sort data=SASUSER.C out=C1;&lt;BR /&gt;
  by B ;&lt;BR /&gt;
data D;&lt;BR /&gt;
  retain _A _C1 _C2;&lt;BR /&gt;
  drop _:;&lt;BR /&gt;
  set C1;&lt;BR /&gt;
  by B;&lt;BR /&gt;
  if _A lt A then do; &lt;BR /&gt;
    _A=A; _C1=C1; _C2=C2; &lt;BR /&gt;
  end;&lt;BR /&gt;
  if last.B; &lt;BR /&gt;
  A=_A; C1=_C1; C2=_C2;&lt;BR /&gt;
run;                                     ******** SORT TO TABLE: 140s median time for 3 runs;&lt;BR /&gt;
 &lt;BR /&gt;
  &lt;BR /&gt;
proc sql;&lt;BR /&gt;
  create view V as select * from SASUSER.C order by B, A;&lt;BR /&gt;
data D1;&lt;BR /&gt;
  set V;&lt;BR /&gt;
  by B;&lt;BR /&gt;
  if last.B;&lt;BR /&gt;
run;                                     ******** SORT TO VIEW: 150s median time for 3 runs;&lt;BR /&gt;
[/pre]&lt;BR /&gt;
&lt;BR /&gt;
If I make the table wider (C2 as $50), the time differences get larger:&lt;BR /&gt;
MPC 185s&lt;BR /&gt;
TABLE 350s&lt;BR /&gt;
VIEW 450s&lt;BR /&gt;
&lt;BR /&gt;
So the view is indeed slower, probably due to using SQL rather than proc sort, as you mention.&lt;BR /&gt;
I'd still use that syntax for small tables as it is a lot easier to read.&lt;BR /&gt;
&lt;BR /&gt;
The most difficult code to read is MPC, but it is also the fastest, saving on I/O. I hope sas will provide local multithreaded syntax soon to do this kind of processing, rather than having to remote submit. It would make the code a lot cleaner.&lt;BR /&gt;
&lt;BR /&gt;
Lastly, in this case we can also use &lt;BR /&gt;
[pre]&lt;BR /&gt;
proc summary data=SASUSER.C nway noprint ;&lt;BR /&gt;
  class B;&lt;BR /&gt;
  var A;&lt;BR /&gt;
  output out=t max= maxid(A(c1))=c1 maxid(A(c2))=c2;&lt;BR /&gt;
run;&lt;BR /&gt;
[/pre]&lt;BR /&gt;
which runs in a mere 23s for the wide table, so is by very far the most efficient.</description>
      <pubDate>Wed, 08 Jul 2009 03:28:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51478#M10812</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-08T03:28:54Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51479#M10813</link>
      <description>Hello Chris.&lt;BR /&gt;
&lt;BR /&gt;
Very good analysis the one you provided.&lt;BR /&gt;
&lt;BR /&gt;
Although very off the original topic, this is getting very interesting.&lt;BR /&gt;
I find it very nice and valuable to have some more academic discussion here.&lt;BR /&gt;
&lt;BR /&gt;
I've ran your tests (3 runs) on my machine (AIX box with 12 lcpu and 20GB of RAM) and added 4 more variants to the solution (code posted at the end):&lt;BR /&gt;
&lt;BR /&gt;
+ Summary Hash technique.&lt;BR /&gt;
+ SORT(one var only)+DATASTEP with Piping Parallelism&lt;BR /&gt;
+ MP(4 parts) SORT(one var only)+DATASTEP with Piping Parallelism&lt;BR /&gt;
+ MP(4 parts) SORT(one var only)+DATASTEP with no Piping Parallelism&lt;BR /&gt;
&lt;BR /&gt;
Results for the same data of your trials:&lt;BR /&gt;
&lt;BR /&gt;
SORT(1VAR)+STEP time=32s, 32s, 32s&lt;BR /&gt;
SQL(2VAR)+STEP time=58s, 57s, 60s&lt;BR /&gt;
PIPED SORT(2VAR)+STEP time=31s, 30s, 31s&lt;BR /&gt;
SUMMARY time=5s, 5s, 5s&lt;BR /&gt;
&lt;BR /&gt;
PIPED SORT(1VAR)+STEP time=26s, 27s, 27s&lt;BR /&gt;
PIPED/MP 4xSORT(1VAR)+STEP time=24s, 25s, 24s&lt;BR /&gt;
HASH SUM time=29s, 30s, 32s&lt;BR /&gt;
MP 4xSORT(1VAR)+STEP time=23s, 25s, 24s&lt;BR /&gt;
&lt;BR /&gt;
Conclusion.&lt;BR /&gt;
SQL worst.&lt;BR /&gt;
Hash not brilliant but, keeps up with the average.&lt;BR /&gt;
Piped Sort by 1 var does a better job than by 2.&lt;BR /&gt;
MP(4 parts) good, but pretty much the same with or without piping.&lt;BR /&gt;
And the gold medal goes for Summary by far.&lt;BR /&gt;
&lt;BR /&gt;
Now, beside the amount of data, two more factors should be considered.&lt;BR /&gt;
&lt;BR /&gt;
Type of data - the generated sample produces only 7 distinct values for B.&lt;BR /&gt;
System load - some techniques (MP/piping and MP+piping) could be greatly influenced by the system load at execution.&lt;BR /&gt;
&lt;BR /&gt;
So I slightly modified your sample to produce about 1000 distinct values for B.&lt;BR /&gt;
Then I ran the same tests (3 runs), and here are the results:&lt;BR /&gt;
&lt;BR /&gt;
SORT(1VAR)+STEP time=59s, 40s, 41s&lt;BR /&gt;
SQL(2VAR)+STEP time=96s, 68s, 89s&lt;BR /&gt;
PIPED SORT(2VAR)+STEP time=215s, 39s, 39s&lt;BR /&gt;
SUMMARY time=63s, 59s, 70s&lt;BR /&gt;
&lt;BR /&gt;
PIPED SORT(1VAR)+STEP time=45s, 44s, 49s&lt;BR /&gt;
PIPED/MP 4xSORT(1VAR)+STEP time=37s, 37s, 68s&lt;BR /&gt;
HASH SUM time=49s, 38s, 36s&lt;BR /&gt;
MP 4xSORT(1VAR)+STEP time=32s, 37s, 177s&lt;BR /&gt;
&lt;BR /&gt;
Conclusion.&lt;BR /&gt;
SQL still worst.&lt;BR /&gt;
Hash not brilliant but, again keeps up with the average.&lt;BR /&gt;
MP/Piping processing produces the best marks, but are highly dependent on the system load, and so less stable in performance.&lt;BR /&gt;
Summary has a lot of more to handle, and goes down on the ranking, very near to SQL performance.&lt;BR /&gt;
&lt;BR /&gt;
So about summing data with SAS, I would conclude by this results, that there is no particular recommended technique. Still, avoid SQL unless for small amount of data.&lt;BR /&gt;
Hash, not being the best, will assure you a good performance, but careful with the memory limitations (roughly I would say a limit of 2,000,000 of distinct elements would be reasonable). &lt;BR /&gt;
Then we have PROC SUMMARY/MEANS which on v9 with its threading support as got a lot better, but, be aware that performance will dramatically reduce with the increase of data, and particularly with the number of distinct elements your grouping.&lt;BR /&gt;
Multi-Processing with or without Piping Parallism, pushes away your processing power, but are alway very dependent on your system load, and results may vary from best to worst.&lt;BR /&gt;
&lt;BR /&gt;
Chris, thank you for pushing this subject a little further, I find it great and mentally challenging to have from time to time this kind of discussion.&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;.</description>
      <pubDate>Thu, 09 Jul 2009 11:25:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51479#M10813</guid>
      <dc:creator>DanielSantos</dc:creator>
      <dc:date>2009-07-09T11:25:38Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51480#M10814</link>
      <description>Now the code.&lt;BR /&gt;
&lt;BR /&gt;
Hash Sum:&lt;BR /&gt;
&lt;BR /&gt;
data _null_;&lt;BR /&gt;
declare hash HT(hashexp: 16); &lt;BR /&gt;
HT.defineKey('B');&lt;BR /&gt;
HT.defineData('B', 'A_MAX', 'C1_MAX', 'C2_MAX');&lt;BR /&gt;
HT.defineDone();&lt;BR /&gt;
do until (_EOF);&lt;BR /&gt;
set LIB.C end = _EOF;&lt;BR /&gt;
if HT.find() or A gt A_MAX then do;&lt;BR /&gt;
A_MAX=A; C1_MAX=C1; C2_MAX=C2;&lt;BR /&gt;
end;&lt;BR /&gt;
HT.replace();&lt;BR /&gt;
end;&lt;BR /&gt;
_RC=HT.output(dataset: 'LIB.D4');&lt;BR /&gt;
run;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
Proc Sort (by one var) and datastep with piping parallelism:&lt;BR /&gt;
&lt;BR /&gt;
signon task1 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
libname OUTLIB sasesock ":9981" timeout=5000;&lt;BR /&gt;
proc sort data=LIB.C out=OUTLIB.C5;&lt;BR /&gt;
    by B;&lt;BR /&gt;
run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task2 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
libname INLIB sasesock ":9981" timeout=5000;&lt;BR /&gt;
data LIB.D5;&lt;BR /&gt;
retain _A _C1 _C2;&lt;BR /&gt;
drop _:;&lt;BR /&gt;
set INLIB.C5;&lt;BR /&gt;
  by B;&lt;BR /&gt;
  if _A lt A then do; &lt;BR /&gt;
    _A=A; _C1=C1; _C2=C2; &lt;BR /&gt;
  end;&lt;BR /&gt;
  if last.B; &lt;BR /&gt;
  A=_A; C1=_C1; C2=_C2;&lt;BR /&gt;
run; &lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
waitfor task2;&lt;BR /&gt;
rget task1;&lt;BR /&gt;
rget task2;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
MP (4 parts) with Proc Sort (by one var) and datastep with piping parallelism:&lt;BR /&gt;
&lt;BR /&gt;
signon task1_1 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_1 wait=no;&lt;BR /&gt;
  libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  libname OUTLIB sasesock ":9971" timeout=5000;&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=1 obs=5000000) out=OUTLIB.C7_1;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_2 wait=no;&lt;BR /&gt;
  libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  libname OUTLIB sasesock ":9972" timeout=5000;&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=5000001 obs=10000000) out=OUTLIB.C7_2;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_3 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_3 wait=no;&lt;BR /&gt;
  libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  libname OUTLIB sasesock ":9973" timeout=5000;&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=10000001 obs=15000000) out=OUTLIB.C7_3;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_4 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_4 wait=no;&lt;BR /&gt;
  libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  libname OUTLIB sasesock ":9974" timeout=5000;&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=15000001 obs=20000000) out=OUTLIB.C7_4;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task2 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
libname INLIB1 sasesock ":9971" timeout=5000;&lt;BR /&gt;
libname INLIB2 sasesock ":9972" timeout=5000;&lt;BR /&gt;
libname INLIB3 sasesock ":9973" timeout=5000;&lt;BR /&gt;
libname INLIB4 sasesock ":9974" timeout=5000;&lt;BR /&gt;
data LIB.D5;&lt;BR /&gt;
  retain _A _C1 _C2;&lt;BR /&gt;
  drop _:;&lt;BR /&gt;
  set INLIB1.C7_1 INLIB2.C7_2 INLIB3.C7_3 INLIB4.C7_4;&lt;BR /&gt;
  by B;&lt;BR /&gt;
  if _A lt A then do; &lt;BR /&gt;
    _A=A; _C1=C1; _C2=C2; &lt;BR /&gt;
  end;&lt;BR /&gt;
  if last.B; &lt;BR /&gt;
  A=_A; C1=_C1; C2=_C2;&lt;BR /&gt;
run; &lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
waitfor task2;&lt;BR /&gt;
rget task1_1;&lt;BR /&gt;
rget task1_2;&lt;BR /&gt;
rget task1_3;&lt;BR /&gt;
rget task1_4;&lt;BR /&gt;
rget task2;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
Finally, MP (4 Parts) Proc Sort (by one var) and datastep without piping parallelism:&lt;BR /&gt;
&lt;BR /&gt;
signon task1_1 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_1 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=1 obs=5000000) out=LIB.C7_1;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_2 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=5000001 obs=10000000) out=LIB.C7_2;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_3 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_3 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=10000001 obs=15000000) out=LIB.C7_3;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
signon task1_4 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task1_4 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
  proc sort data=LIB.C (firstobs=15000001 obs=20000000) out=LIB.C7_4;&lt;BR /&gt;
    by B;&lt;BR /&gt;
  run;&lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
*rdisplay task1;&lt;BR /&gt;
waitfor _all_ task1_1 task1_2 task1_3 task1_4;&lt;BR /&gt;
signon task2 sascmd="!sascmd";&lt;BR /&gt;
rsubmit task2 wait=no;&lt;BR /&gt;
libname LIB '/batch/sas/SASTMP';&lt;BR /&gt;
data LIB.D7;&lt;BR /&gt;
  retain _A _C1 _C2;&lt;BR /&gt;
  drop _:;&lt;BR /&gt;
  set LIB.C7_1 LIB.C7_2 LIB.C7_3 LIB.C7_4;&lt;BR /&gt;
  by B;&lt;BR /&gt;
  if _A lt A then do; &lt;BR /&gt;
    _A=A; _C1=C1; _C2=C2; &lt;BR /&gt;
  end;&lt;BR /&gt;
  if last.B; &lt;BR /&gt;
  A=_A; C1=_C1; C2=_C2;&lt;BR /&gt;
run; &lt;BR /&gt;
endrsubmit;&lt;BR /&gt;
waitfor task2;&lt;BR /&gt;
rget task1_1;&lt;BR /&gt;
rget task1_2;&lt;BR /&gt;
rget task1_3;&lt;BR /&gt;
rget task1_4;&lt;BR /&gt;
rget task2;&lt;BR /&gt;
&lt;BR /&gt;
Cheers from Portugal.&lt;BR /&gt;
&lt;BR /&gt;
Daniel Santos @ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;.</description>
      <pubDate>Thu, 09 Jul 2009 11:31:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51480#M10814</guid>
      <dc:creator>DanielSantos</dc:creator>
      <dc:date>2009-07-09T11:31:31Z</dc:date>
    </item>
    <item>
      <title>Re: PLZ: Macro Urgent Help</title>
      <link>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51481#M10815</link>
      <description>Mmm, interesting. I woud never have thought of splitting the sort.&lt;BR /&gt;
This is probably the wrong place to prolong this discussion, though.&lt;BR /&gt;
As usual when discussing performance, the answer is: it depends on the data and what you do with it, which makes sizing the right box for a data warehouse so difficult.</description>
      <pubDate>Thu, 09 Jul 2009 21:34:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/PLZ-Macro-Urgent-Help/m-p/51481#M10815</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2009-07-09T21:34:59Z</dc:date>
    </item>
  </channel>
</rss>

