<?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: Proc SQL Keep Last n in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935616#M367849</link>
    <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/464455"&gt;@KMWWN156&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;I need to keep the latest dated transactions, so if sorting &lt;FONT color="#FF0000"&gt;&lt;U&gt;Ascending&lt;/U&gt;&lt;/FONT&gt;, then it would be the &lt;STRIKE&gt;first&lt;/STRIKE&gt; &lt;FONT color="#FF0000"&gt;last&lt;/FONT&gt; 20, if descending it would be the last 20&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Does that change anything within the code as i cant seem to get the results i want.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Sort DESCENDING to use FIRST 20.&lt;/P&gt;
&lt;PRE&gt;Proc sort data=Transactions;
  by Accno descending TranDate;
run;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 12 Jul 2024 14:58:13 GMT</pubDate>
    <dc:creator>ballardw</dc:creator>
    <dc:date>2024-07-12T14:58:13Z</dc:date>
    <item>
      <title>Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935588#M367840</link>
      <description>&lt;P&gt;I am looking at a large dataset of payment values and want to keep the last 20 records per account - How would i do this? Probably very simple but cannot figure this out. Example code for keeping last 1 record per account is as follows.&lt;/P&gt;&lt;P&gt;Data TransRef;&lt;BR /&gt;Set Transactions;&lt;BR /&gt;by Accno TranDate;&lt;BR /&gt;If Last.Accno;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;P&gt;I have tried OBS and retain but no luck&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2024 13:40:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935588#M367840</guid>
      <dc:creator>KMWWN156</dc:creator>
      <dc:date>2024-07-12T13:40:22Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935591#M367842</link>
      <description>&lt;P&gt;To keep the LAST 20 observations when ordered in that way you would need to know how many observations there were for each BY value.&amp;nbsp; One way would be to make two passes thru the data for each BY group.&amp;nbsp; One to count. One to actually output.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data TransRef;
  do nrows=1 by 1 until(last.accno);
    set Transactions;
    by Accno TranDate;
  end;
  do row=1 to nrows;
    set Transactions;
    if row &amp;gt;= (nrows-20) then output;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But if you read the data by DESCENDING date then your request converts to finding the FIRST 20 observations.&amp;nbsp; Which is much easier.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data TransRef;
  set Transactions;
  by Accno descending TranDate;
  if first.Accno then row=1;
  else row+1;
  if row &amp;lt;= 20 ;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 12 Jul 2024 13:50:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935591#M367842</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2024-07-12T13:50:18Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935613#M367847</link>
      <description>&lt;P&gt;I need to keep the latest dated transactions, so if sorting Ascending, then it would be the first 20, if descending it would be the last 20&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Does that change anything within the code as i cant seem to get the results i want.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks,&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2024 14:39:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935613#M367847</guid>
      <dc:creator>KMWWN156</dc:creator>
      <dc:date>2024-07-12T14:39:46Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935616#M367849</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/464455"&gt;@KMWWN156&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;I need to keep the latest dated transactions, so if sorting &lt;FONT color="#FF0000"&gt;&lt;U&gt;Ascending&lt;/U&gt;&lt;/FONT&gt;, then it would be the &lt;STRIKE&gt;first&lt;/STRIKE&gt; &lt;FONT color="#FF0000"&gt;last&lt;/FONT&gt; 20, if descending it would be the last 20&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Does that change anything within the code as i cant seem to get the results i want.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Sort DESCENDING to use FIRST 20.&lt;/P&gt;
&lt;PRE&gt;Proc sort data=Transactions;
  by Accno descending TranDate;
run;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2024 14:58:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935616#M367849</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2024-07-12T14:58:13Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935635#M367854</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/464455"&gt;@KMWWN156&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;I need to keep the latest dated transactions, so if sorting Ascending, then it would be the first 20, if descending it would be the last 20&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Does that change anything within the code as i cant seem to get the results i want.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Seems like you are saying contradictory things.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In English "latest date" means the most recent dates. So the largest dates.&amp;nbsp; Which would the last few observations when sorted by ascending.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you mean the oldest dates (or the earliest dates) then that would be the first few observations when sorted by&amp;nbsp; ascending dates.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 12 Jul 2024 17:40:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935635#M367854</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2024-07-12T17:40:59Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935680#M367863</link>
      <description>&lt;P&gt;I assume your data are already sorted by ACCNO/TRANDATE.&amp;nbsp; &amp;nbsp;True, sorting by descending date (within each ACCNO) would allow you to take the first 20 of each ACCNO, a relatively straightforward process.&amp;nbsp; But sorting is expensive, and you might need to re-sort the results by ascending date.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;EDIT:&amp;nbsp; Please see revised code at the end of this note.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So here is a two pass process (passing through each ACCNO twice, but in the original order:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data transfer (drop=_:);
  set transactions (in=firstpass)
      transactions (in=secondpass) ;
  by accnow;
  _n1 + firstpass;
  _n2 + secondpass;
  if secondpass=1 and _n2&amp;gt;= _n1-20;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Even though you pass through the entire dataset twice, it won't require twice the data-reading resources, because the SET statement interleaves the firstpass for a given ACCNO with the secondpass for the same ACCNO.&amp;nbsp; Since the most recently read observations (from firstpass) will be cached in memory, they will therefore be available to the secondpass without rereading data from the storage device.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;EDIT:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I realized the subsetting IF was providing 21 (not 20) observations for each ACCNOW.&amp;nbsp; The code should have used&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;_n2 &amp;gt; _n1-20 &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;instead of&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;_n2 &amp;gt;= _n1-20 &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But there is also a second problem.&amp;nbsp; The code above works fine for each ACCNOW that has 20 or more observations.&amp;nbsp; But it also outputs all observations for any ACCNOW group with fewer than 20 obs.&amp;nbsp; If you want to exclude such small groups, then:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data transfer;
  set transactions (in=firstpass)
      transactions (in=secondpass) ;
  by accnow;
  if first.accnow then call missing(_n1,_n2);
  _n1 + firstpass;
  _n2 + secondpass;
  if secondpass=1 and _n1&amp;gt;=20 and _n2 &amp;gt; _n1-20 ;
run;&lt;/CODE&gt;&lt;/PRE&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>Thu, 18 Jul 2024 02:55:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935680#M367863</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-07-18T02:55:47Z</dc:date>
    </item>
    <item>
      <title>Re: Proc SQL Keep Last n</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935690#M367866</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sort data=sashelp.stocks out=have;
by stock date;
run;
data want;
 merge have have(keep=stock rename=(stock=_stock) firstobs=21);
 if stock ne _stock;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Or Check&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13684"&gt;@Rick_SAS&lt;/a&gt; blog:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://blogs.sas.com/content/iml/2024/07/10/largest-values-for-group.html" target="_blank"&gt;https://blogs.sas.com/content/iml/2024/07/10/largest-values-for-group.html&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 13 Jul 2024 06:39:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Proc-SQL-Keep-Last-n/m-p/935690#M367866</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-07-13T06:39:47Z</dc:date>
    </item>
  </channel>
</rss>

