<?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 REMOVEDUP and REPLACEDUP in HASH Object in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673791#M202756</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;I tested this code&lt;/P&gt;
&lt;PRE&gt;data h ;&lt;BR /&gt;input key hdata ;&lt;BR /&gt;cards ;&lt;BR /&gt;1 5&lt;BR /&gt;1 10&lt;BR /&gt;1 15 &lt;BR /&gt;2 9&lt;BR /&gt;2 11&lt;BR /&gt;2 16&lt;BR /&gt;3 20&lt;BR /&gt;3 100&lt;BR /&gt;4 6&lt;BR /&gt;5 5&lt;BR /&gt;5 99&lt;BR /&gt;;&lt;BR /&gt;run ;&lt;BR /&gt;&lt;BR /&gt;data _null_ ;&lt;BR /&gt; if 0 then set H ;&lt;BR /&gt; dcl hash H (dataset: "H", multidata: "Y", ordered: "A") ;&lt;BR /&gt; h.definekey ("key") ;&lt;BR /&gt; h.definedata ("key", "hdata") ;&lt;BR /&gt; h.definedone () ;&lt;BR /&gt;&lt;BR /&gt; do key = 1, 2, 5 ;&lt;BR /&gt;   put '01 - key est ' key;&lt;BR /&gt;   do find_rc = h.find() by 0 while (find_rc = 0) ;&lt;BR /&gt;     put ' au do find, find_rc est ' find_rc;&lt;BR /&gt;     put '  02 - hdata est ' hdata;&lt;BR /&gt;     if hdata &amp;gt; 9 then remove_rc = h.removedup() ;&lt;BR /&gt;     put '   03 - remove_rc est ' remove_rc;&lt;BR /&gt;     find_rc = h.find_next() ;&lt;BR /&gt;     put '    04 - find_rc est ' find_rc;&lt;BR /&gt;   end ;&lt;BR /&gt; end ;&lt;BR /&gt;&lt;BR /&gt; dcl hiter ih ("H") ;&lt;BR /&gt; &lt;BR /&gt; do while (ih.next() = 0) ;&lt;BR /&gt;   put key= hdata= ;&lt;BR /&gt; end ;&lt;BR /&gt;run ; &lt;BR /&gt;&lt;BR /&gt;AND GOT THIS RESULT:&lt;/PRE&gt;
&lt;DIV id="sasLogNote3_1596214150465" class="sasNote"&gt;NOTE: There were 11 observations read from the data set WORK.H.&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 1&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est .&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 10&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 2&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 9&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 11&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 99&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=1 hdata=5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=1 hdata=15&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=2 hdata=9&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=2 hdata=16&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=3 hdata=20&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=3 hdata=100&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=4 hdata=6&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=5 hdata=5&lt;/DIV&gt;
&lt;DIV id="sasLogNote4_1596214150465" class="sasNote"&gt;NOTE: DATA STEP stopped due to looping.&lt;/DIV&gt;
&lt;DIV id="sasLogNote5_1596214150465" class="sasNote"&gt;NOTE: DATA statement a utilisé (Durée totale du traitement) :&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;real time 0.02 seconds&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;cpu time 0.02 seconds&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;In the second 04 printing, I was expecting a 0 , cause there is in fact a next.&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;What is that 160038 ????&amp;nbsp; It makes absolutely NO SENSE !!!&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;And it goes on for others as well. . .&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;You can email me at &lt;A href="mailto:michel.jubinville@hotmail.ca" target="_blank"&gt;michel.jubinville@hotmail.ca&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;Thanks&lt;/DIV&gt;
&lt;PRE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 31 Jul 2020 17:23:14 GMT</pubDate>
    <dc:creator>Mij</dc:creator>
    <dc:date>2020-07-31T17:23:14Z</dc:date>
    <item>
      <title>REMOVEDUP and REPLACEDUP in HASH Object</title>
      <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673791#M202756</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;I tested this code&lt;/P&gt;
&lt;PRE&gt;data h ;&lt;BR /&gt;input key hdata ;&lt;BR /&gt;cards ;&lt;BR /&gt;1 5&lt;BR /&gt;1 10&lt;BR /&gt;1 15 &lt;BR /&gt;2 9&lt;BR /&gt;2 11&lt;BR /&gt;2 16&lt;BR /&gt;3 20&lt;BR /&gt;3 100&lt;BR /&gt;4 6&lt;BR /&gt;5 5&lt;BR /&gt;5 99&lt;BR /&gt;;&lt;BR /&gt;run ;&lt;BR /&gt;&lt;BR /&gt;data _null_ ;&lt;BR /&gt; if 0 then set H ;&lt;BR /&gt; dcl hash H (dataset: "H", multidata: "Y", ordered: "A") ;&lt;BR /&gt; h.definekey ("key") ;&lt;BR /&gt; h.definedata ("key", "hdata") ;&lt;BR /&gt; h.definedone () ;&lt;BR /&gt;&lt;BR /&gt; do key = 1, 2, 5 ;&lt;BR /&gt;   put '01 - key est ' key;&lt;BR /&gt;   do find_rc = h.find() by 0 while (find_rc = 0) ;&lt;BR /&gt;     put ' au do find, find_rc est ' find_rc;&lt;BR /&gt;     put '  02 - hdata est ' hdata;&lt;BR /&gt;     if hdata &amp;gt; 9 then remove_rc = h.removedup() ;&lt;BR /&gt;     put '   03 - remove_rc est ' remove_rc;&lt;BR /&gt;     find_rc = h.find_next() ;&lt;BR /&gt;     put '    04 - find_rc est ' find_rc;&lt;BR /&gt;   end ;&lt;BR /&gt; end ;&lt;BR /&gt;&lt;BR /&gt; dcl hiter ih ("H") ;&lt;BR /&gt; &lt;BR /&gt; do while (ih.next() = 0) ;&lt;BR /&gt;   put key= hdata= ;&lt;BR /&gt; end ;&lt;BR /&gt;run ; &lt;BR /&gt;&lt;BR /&gt;AND GOT THIS RESULT:&lt;/PRE&gt;
&lt;DIV id="sasLogNote3_1596214150465" class="sasNote"&gt;NOTE: There were 11 observations read from the data set WORK.H.&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 1&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est .&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 10&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 2&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 9&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 11&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;01 - key est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;au do find, find_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;02 - hdata est 99&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;03 - remove_rc est 0&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;04 - find_rc est 160038&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=1 hdata=5&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=1 hdata=15&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=2 hdata=9&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=2 hdata=16&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=3 hdata=20&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=3 hdata=100&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=4 hdata=6&lt;/DIV&gt;
&lt;DIV class="sasSource"&gt;key=5 hdata=5&lt;/DIV&gt;
&lt;DIV id="sasLogNote4_1596214150465" class="sasNote"&gt;NOTE: DATA STEP stopped due to looping.&lt;/DIV&gt;
&lt;DIV id="sasLogNote5_1596214150465" class="sasNote"&gt;NOTE: DATA statement a utilisé (Durée totale du traitement) :&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;real time 0.02 seconds&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;cpu time 0.02 seconds&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;In the second 04 printing, I was expecting a 0 , cause there is in fact a next.&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;What is that 160038 ????&amp;nbsp; It makes absolutely NO SENSE !!!&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;And it goes on for others as well. . .&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;You can email me at &lt;A href="mailto:michel.jubinville@hotmail.ca" target="_blank"&gt;michel.jubinville@hotmail.ca&lt;/A&gt;&lt;/DIV&gt;
&lt;DIV class="sasNote"&gt;Thanks&lt;/DIV&gt;
&lt;PRE&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 31 Jul 2020 17:23:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673791#M202756</guid>
      <dc:creator>Mij</dc:creator>
      <dc:date>2020-07-31T17:23:14Z</dc:date>
    </item>
    <item>
      <title>Re: REMOVEDUP and REPLACEDUP in HASH Object</title>
      <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673888#M202811</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/44828"&gt;@Mij&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Yes, some of the hash object methods (including REMOVEDUP, not to mention SUMDUP ...) have their intricacies. Not all of those details are easily available in the documentation or in books about the subject. At some point you may want to perform your own experiments.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The particular issue in your code, however, is well described and solved in sections 4.3.11 and 4.3.12 of the book [1]&amp;nbsp;&lt;A href="https://www.sas.com/store/books/categories/examples/data-management-solutions-using-sas-hash-table-operations-a-business-intelligence-case-study/prodBK_69153_en.html" target="_blank" rel="noopener"&gt;Data Management Solutions Using SAS® Hash Table Operations: A Business Intelligence Case Study&lt;/A&gt;&amp;nbsp;and also in chapter 5 (pp. 129, 136 f.) of the book&amp;nbsp;[2]&amp;nbsp;&lt;A href="https://www.sas.com/store/books/categories/usage-and-reference/sas-hash-object-programming-made-easy/prodBK_62230_en.html" target="_blank" rel="noopener"&gt;SAS® Hash Object Programming Made Easy&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once REMOVEDUP has removed an item from a same-key item group, SAS (unfortunately) has forgotten where it was in that group -- it "&lt;EM&gt;unsets the item list&lt;/EM&gt;" ([1], p. 90), in other words: "sets the pointers to null" ([2], p. 129) --, hence the nonzero return code 160038 you received from the FIND_NEXT method. &lt;FONT color="#999999"&gt;To remove more (but not all) items of the group, you need to set the pointer to the first item of that group again (using FIND or DO_OVER or CHECK or REF), move the pointer to the next item to be deleted (using FIND_NEXT/FIND_PREV or DO_OVER), if necessary, and repeat these steps until all deletions are done. The HAS_NEXT method can be used in this process to find out if there are more items in the group which may or may not qualify for deletion (see program 4.12 in [1], p. 91).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;EDIT:&lt;/STRONG&gt;&amp;nbsp;I've just discovered that in my SAS 9.4&lt;U&gt;M5&lt;/U&gt; &lt;EM&gt;DO_OVER&lt;/EM&gt; seems to play well with REMOVEDUP, so you would no longer need an outer loop to restart the enumeration of a group with two or more items to be removed, nor the HAS_NEXT method to support this iteration (as suggested on p. 92 of [1]). Instead, you can simply write something like&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt; do key = 1, 2, 5;
   do while(h.do_over()=0);
     if hdata &amp;gt; 9 then h.removedup();
   end;
 end;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;in order to selectively remove items from same-key item groups. Not sure in which maintenance release this has been enabled. I haven't found a hint about this change in the documentation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So, to reiterate, you can gain new insights by performing your own experiments.&lt;/P&gt;</description>
      <pubDate>Sat, 01 Aug 2020 12:31:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673888#M202811</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2020-08-01T12:31:07Z</dc:date>
    </item>
    <item>
      <title>Re: REMOVEDUP and REPLACEDUP in HASH Object</title>
      <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673945#M202843</link>
      <description>&lt;P&gt;Thanks. In the paper I'm reading, do_over is not mentionned. I guess it came with SAS 9.4.&lt;/P&gt;
&lt;P&gt;BTW, I bought the 2 books today.&lt;/P&gt;</description>
      <pubDate>Sat, 01 Aug 2020 20:10:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673945#M202843</guid>
      <dc:creator>Mij</dc:creator>
      <dc:date>2020-08-01T20:10:43Z</dc:date>
    </item>
    <item>
      <title>Re: REMOVEDUP and REPLACEDUP in HASH Object</title>
      <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673985#M202868</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/32733"&gt;@FreelanceReinh&lt;/a&gt;&amp;nbsp;very nice explanation. Quite interesting that the Removedup Method does not unset the item list when Do_Over is used instead of the Find()/Has_Next()/Find_Next() approach. This seems to be te case at least from 9.4M3. Can't seem to find any doc mention it. That simplifies the selective deletion operation quite a bit..&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/44828"&gt;@Mij&lt;/a&gt;&amp;nbsp;kudos for the curiosity. I'm sure you will find many great hash tips in the two books &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 02 Aug 2020 11:56:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673985#M202868</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2020-08-02T11:56:50Z</dc:date>
    </item>
    <item>
      <title>Re: REMOVEDUP and REPLACEDUP in HASH Object</title>
      <link>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673994#M202871</link>
      <description>The books will be mine next Friday. Pretty sure I'll find lots of interesting stuff.&lt;BR /&gt;Thanks and have a nice day.</description>
      <pubDate>Sun, 02 Aug 2020 15:14:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/REMOVEDUP-and-REPLACEDUP-in-HASH-Object/m-p/673994#M202871</guid>
      <dc:creator>Mij</dc:creator>
      <dc:date>2020-08-02T15:14:00Z</dc:date>
    </item>
  </channel>
</rss>

