<?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: Mark top 3 values by group (improve code efficiency) in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846994#M334859</link>
    <description>&lt;P&gt;For curiosity, Yes. For efficiency, No &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; There will be virtually no gain in efficiency from that.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you're looking to speed things up or other measures of better performance when doing this, you should try to develop a method without the Sort Procedure &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
    <pubDate>Wed, 30 Nov 2022 07:51:46 GMT</pubDate>
    <dc:creator>PeterClemmensen</dc:creator>
    <dc:date>2022-11-30T07:51:46Z</dc:date>
    <item>
      <title>Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846952#M334843</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;My code below helps to mark the top 3 value for each ID.&lt;/P&gt;
&lt;P&gt;However, as you see, SAS will assign top number for every rows which is unnecessary.&lt;/P&gt;
&lt;P&gt;For the sake of curiosity and efficiency, is there any way to tell SAS stop assigning value after top=3?&lt;/P&gt;
&lt;P&gt;Thank you,&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input  ID value  ;
cards;
1 5
1 8
1 2
1 0
2 6
2 10
2 9
2 1 
2 5
2 33
run;

proc sort data=have; 
by id descending value;
run;

data want; set have;
by id;
if first.id then top=0;
top+1;
retain top;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 30 Nov 2022 00:56:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846952#M334843</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2022-11-30T00:56:29Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846954#M334845</link>
      <description>&lt;P&gt;How about this?&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input  ID value  ;
cards;
1 5
1 8
1 2
1 0
2 6
2 10
2 9
2 1 
2 5
2 33
run;

proc sort data=have; 
by id descending value;
run;

data want; set have;
by id;
if first.id then top = 0;
if 0 &amp;lt;= top &amp;lt; 3 then top + 1;
else top = .;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 30 Nov 2022 01:22:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846954#M334845</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-11-30T01:22:55Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846994#M334859</link>
      <description>&lt;P&gt;For curiosity, Yes. For efficiency, No &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; There will be virtually no gain in efficiency from that.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you're looking to speed things up or other measures of better performance when doing this, you should try to develop a method without the Sort Procedure &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 30 Nov 2022 07:51:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/846994#M334859</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2022-11-30T07:51:46Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847007#M334867</link>
      <description>&lt;P&gt;As&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31304"&gt;@PeterClemmensen&lt;/a&gt;&amp;nbsp;remarked, if you have performance problems, it may help doing things without the proc sort.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is a method that works without sorting the data.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First, generate the top 3 records for each id, with an index:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data top3 (index=(idx=(ID value)));
  set have;
  by ID;
  array top4(4) 8 _temporary_;
  if first.id then 
    call missing(of top4(*));
  if value&amp;gt;top4(1) then do;
    top4(1)=value;
    call sortn(of top4(*));
    end;
  if last.id;
  n=n(of top4(*));
  do _N_=max(n-2,1) to min(n,4);
    value=top4(_N_);
    top=n-_N_+1;
    output;
    end;
  keep id value top;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then use that to get the data you want:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  set have;
  top=.;
  set top3 key=idx/unique;
  if _iorc_ then 
    _error_=0;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This may run faster if it is the sort that takes time.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You did not specify what to do with ties. This method assigns the same top value to ties, unlike your original program which assigns different numbers. So if you have data like&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input  ID value  ;
cards;
1 5
1 8
1 2
1 2&lt;BR /&gt;1 0
;run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;the output from this program will look like&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input  ID value  top;
cards;
1 5 2
1 8 1
1 2 3
1 2 3&lt;BR /&gt;1 0 .
;run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;while the output from your program will be&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input  ID value  top;
cards;
1 8 1
1 5 2
1 2 3
1 2 4
1 0 5
;run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;- if you do not set TOP to missing after the first 3, that is. But doing that will hardly save any CPU time.&lt;/P&gt;</description>
      <pubDate>Wed, 30 Nov 2022 10:21:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847007#M334867</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2022-11-30T10:21:40Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847051#M334892</link>
      <description>&lt;P&gt;I don't think that avoiding proc sort improves the runtime. I got the following times, when have had 1000000 obs (100k ids, 10 obs each):&lt;/P&gt;
&lt;DIV class="sasSource"&gt;original code: duration=0.265001&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;suggestion by &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt;: duration=1.282&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;summary+transpose+hash: duration=0.859&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;Code of the hash-approach:&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc summary data=have nway;
   class id;
   var value;
   output out= work.top max= idgroup(max(value) out[3] (value)=maxvalue );
run;

proc transpose data=work.top(keep= id maxvalue:) out=work.transposed(rename=(col1 = value)) name=position;
   by id;
   var maxvalue:;
run;

data want;
   set have;
   
   if _n_ = 1 then do;
      if 0 then set work.transposed;
      declare hash h(dataset: 'work.transposed');
      h.defineKey('id', 'value');
      h.defineData('position');
      h.defineDone();
   end;
   
   if h.find() = 0 then do;
      top = input(compress(position,, 'kd'), 1.);
   end;
   
   drop position;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;P&gt;&lt;LI-WRAPPER&gt;&lt;/LI-WRAPPER&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 30 Nov 2022 14:31:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847051#M334892</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2022-11-30T14:31:28Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847172#M334952</link>
      <description>&lt;P&gt;Thank you all for an interesting discussion.&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;</description>
      <pubDate>Thu, 01 Dec 2022 01:05:30 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/847172#M334952</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2022-12-01T01:05:30Z</dc:date>
    </item>
    <item>
      <title>Re: Mark top 3 values by group (improve code efficiency)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/852173#M336880</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want; set have;
by id;
if first.id then do;
	n=1;
	top=0;
	end;
if n&amp;lt;=3 then top+1;
else top=.;
n+1;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 04 Jan 2023 18:07:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Mark-top-3-values-by-group-improve-code-efficiency/m-p/852173#M336880</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2023-01-04T18:07:19Z</dc:date>
    </item>
  </channel>
</rss>

