<?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: de-dup array in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96131#M20232</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;The will be a brute force method, but don't blame me, blame Mark Keintz :smileysilly:. Since you are dealing with phone numbers, so there will be a scope, And if your phone numbers do not have '-', () embedded, you can try the following, otherwise, you will need to convert your data a little bit:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; infile datalines dsd truncover;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input person $ phone1-phone3;&lt;/P&gt;&lt;P&gt;array p1(1:1000) _temporary_ (1000*0);&lt;/P&gt;&lt;P&gt;array p2 phone:;&lt;/P&gt;&lt;P&gt;do i=1 to dim(p2);&lt;/P&gt;&lt;P&gt;if not missing(p2(i)) then p1(p2(i))=1;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;call missing(of p2(*));&lt;/P&gt;&lt;P&gt;do&amp;nbsp; i=1 to 1000;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if p1(i)=1 then do ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; j+1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p2(j)=i;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;call missing(of i,j,of p1(*));&lt;/P&gt;&lt;P&gt;drop i j;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;A,111,222,111&lt;/P&gt;&lt;P&gt;B,,444,444&lt;/P&gt;&lt;P&gt;C,111,,222,&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;/P&gt;&lt;P&gt;proc print;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Haikuo&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 16 Aug 2012 13:14:12 GMT</pubDate>
    <dc:creator>Haikuo</dc:creator>
    <dc:date>2012-08-16T13:14:12Z</dc:date>
    <item>
      <title>de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96129#M20230</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi all&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm having phone numbers per person ('data have'). What I need to do is to get rid of duplicate phone numbers per row (result should be like 'data want').&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;To have the phone numbers also "left aligned" like in 'data want' would be a "nice to have" but is not crucial.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;What is crucial: The de-duping must happen within a single data step (so in below example everything should happen within 'data have') because I need a solution which I then can apply on 40M rows (so using Proc Transpose or the like is not an option).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;....and the code must work with SAS9.1.3&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;BR /&gt;&amp;nbsp; infile datalines dsd truncover;&lt;BR /&gt;&amp;nbsp; input person $ phone1-phone3;&lt;BR /&gt;&amp;nbsp; datalines;&lt;BR /&gt;A,111,222,111&lt;BR /&gt;B,,444,444&lt;BR /&gt;C,111,,222,&lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want;&lt;BR /&gt;&amp;nbsp; infile datalines dsd truncover;&lt;BR /&gt;&amp;nbsp; input person $ phone1-phone3;&lt;BR /&gt;&amp;nbsp; datalines;&lt;BR /&gt;A,111,222&lt;BR /&gt;B,444&lt;BR /&gt;C,111,222&lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;P&gt;Patrick&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Message was edited by: Patrick &lt;BR /&gt; @Art: It was a typo. Data fixed.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&#xD;
&#xD;
Just to add one more piece of information which might help:&#xD;
You can work under the assumption that the phone numbers only contain digits&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 12:31:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96129#M20230</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2012-08-16T12:31:53Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96130#M20231</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&amp;nbsp; Unless that was a typo, for the first record of want, I think we need more explanation of what you want.&amp;nbsp; I would have expected that you would want:&lt;/P&gt;&lt;P&gt;A,111,222&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 12:40:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96130#M20231</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T12:40:03Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96131#M20232</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;The will be a brute force method, but don't blame me, blame Mark Keintz :smileysilly:. Since you are dealing with phone numbers, so there will be a scope, And if your phone numbers do not have '-', () embedded, you can try the following, otherwise, you will need to convert your data a little bit:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; infile datalines dsd truncover;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input person $ phone1-phone3;&lt;/P&gt;&lt;P&gt;array p1(1:1000) _temporary_ (1000*0);&lt;/P&gt;&lt;P&gt;array p2 phone:;&lt;/P&gt;&lt;P&gt;do i=1 to dim(p2);&lt;/P&gt;&lt;P&gt;if not missing(p2(i)) then p1(p2(i))=1;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;call missing(of p2(*));&lt;/P&gt;&lt;P&gt;do&amp;nbsp; i=1 to 1000;&lt;/P&gt;&lt;P&gt;&amp;nbsp; if p1(i)=1 then do ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; j+1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p2(j)=i;&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;call missing(of i,j,of p1(*));&lt;/P&gt;&lt;P&gt;drop i j;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;A,111,222,111&lt;/P&gt;&lt;P&gt;B,,444,444&lt;/P&gt;&lt;P&gt;C,111,,222,&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;/P&gt;&lt;P&gt;proc print;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Haikuo&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 13:14:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96131#M20232</guid>
      <dc:creator>Haikuo</dc:creator>
      <dc:date>2012-08-16T13:14:12Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96132#M20233</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Here is an alternative approach that was suggested by Paul Dorfman in an older (2005) SAS-L post.&amp;nbsp; The approach is quite useful as the only thing one has to change in order to deal with character variables is to make the array character.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Anyhow, it lets you sort in either ascending or descending order, as well as gets rid of duplicates:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; infile datalines dsd truncover;&lt;/P&gt;&lt;P&gt;&amp;nbsp; input person $ phone1-phone3;&lt;/P&gt;&lt;P&gt;&amp;nbsp; datalines;&lt;/P&gt;&lt;P&gt;A,111,222,111&lt;/P&gt;&lt;P&gt;B,,444,444&lt;/P&gt;&lt;P&gt;C,111,,222,&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;data want;&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array numbers(*) phone1-phone3;&lt;/P&gt;&lt;P&gt;** set sort parameters (hint: would-be macro parms) ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; seq&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 'A' ; * A = ascending, D = descending ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; nodupkey =&amp;nbsp; 1&amp;nbsp; ; * 0 = duplicates allowed, 1 = duplicates not allowed ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; dcl hash&amp;nbsp; _hh&amp;nbsp; (hashexp: 16, ordered: seq) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; dcl hiter _hi&amp;nbsp; ('_hh'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _hh.definekey&amp;nbsp; ('_k', '_n'&amp;nbsp; ) ; * _n - extra enumerating key ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _hh.definedata ('_k'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ; * _k automatically assumes array data type ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _hh.definedone (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;** load composite (_k _n) key on the table&amp;nbsp;&amp;nbsp; ;&lt;/P&gt;&lt;P&gt;** if duplicates to be retained, set 0 &amp;lt;- _n ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _j = lbound (numbers) to hbound (numbers) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _n = _j * ^ nodupkey ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _k = numbers [_j] ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _hh.replace() ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;** use iterator HI to reload array from HH table, now in order ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _n = lbound (numbers) - 1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _rc = _hi.first() by 0 while ( _rc = 0 ) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _n = _n + 1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers [_n] = _k ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc = _hi.next() ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _q = _n ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;** fill array tail with missing values if duplicates are delete ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _n = _q + 1 to hbound (numbers) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers [_n] = . ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; drop _: ; * drop auxiliary variables ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 13:46:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96132#M20233</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T13:46:12Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96133#M20234</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Art,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If I understand this correctly (and I'm a ways from that at this point), you are rebuilding the hash table for each observation.&amp;nbsp; I'm going to have to study this a bit.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Traditionally, the biggest problem in these situations was putting all phone numbers into the same format.&amp;nbsp; Enhancements to COMPRESS (using kd as the third parameter) have made this step easy.&amp;nbsp; If you only have three phone numbers, you can always code:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;if phone1=phone2 then phone2=' ';&lt;/P&gt;&lt;P&gt;if phone1=phone3 then phone3=' ';&lt;/P&gt;&lt;P&gt;if phone2=phone3 then phone3=' ';&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;That won't handle the order problem, but that could be tackled as a next step.&amp;nbsp; If you actually have more phone numbers, you might switch to arrays:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;array phones {*} phone:;&lt;/P&gt;&lt;P&gt;do i=1 to dim(phone)-1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do j=i+1 to dim(phone);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if phones{i}=phones{j} then phones{j}=' ';&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;end;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I like the hashing approach ... I'm just not up to speed on it yet.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Good luck.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 13:58:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96133#M20234</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2012-08-16T13:58:59Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96134#M20235</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Astounding: What I'd really like to see is a nodupkey option added to call sortn and call sortc, but I don't know if we're ever going to see that.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:05:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96134#M20235</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T14:05:06Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96135#M20236</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I like it, Art. I believe this is more suitable for Patrick's daunting 40M records. Haikuo&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:07:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96135#M20236</guid>
      <dc:creator>Haikuo</dc:creator>
      <dc:date>2012-08-16T14:07:34Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96136#M20237</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Haikuo&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My phone numbers contain only digits so no problems from this side. The code you've posted is quite clever but - and it's a big BUT - it is very wastefull with memory.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm having in real life much longer phone numbers. I've tried your code with 11 digits so I had to create 10**12 temporary array elements. It took only seconds to get an out-of-memory error (and I've got 8GB of RAM on my test laptop). &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So: Very interesting solution but not fit-for-purpose unfortunately.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;P&gt;Patrick&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:07:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96136#M20237</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2012-08-16T14:07:41Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96137#M20238</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;I know mine is hopelessly flawed for your real problem. The good thing is, Art 's solution is much much better.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Haikuo&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:16:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96137#M20238</guid>
      <dc:creator>Haikuo</dc:creator>
      <dc:date>2012-08-16T14:16:06Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96138#M20239</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Art, Haikuo, Astounding&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks a lot for your fast and valuable replies.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;@Art&lt;/P&gt;&lt;P&gt;I was actually thinking about using a hash/iter object combination but I couldn't figure out of how to do it in a way that I wouldn't have to create and destroy the objects for every single iteration of the data step. I even was looking for papers from the master of hash (Paul Dorfman) but couldn't find the right one.&lt;/P&gt;&lt;P&gt;Thanks a lot for this. I will still need some time to fully digest this code but considering the author I have no doubt that it's kind of final and can't be bettered.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:24:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96138#M20239</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2012-08-16T14:24:15Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96139#M20240</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick: And, since Paul has been known to occasionally read and respond to the forum posts, if he has come up with a more optimal solution, I would guess that we'll hear from him directly.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:37:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96139#M20240</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T14:37:07Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96140#M20241</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;clear() method can been found in&amp;nbsp; 9.2, It clears hash() without delete the object instance. I have no idea its overhead comparing to generating new hash() each record, and I don't know if it is at your disposal for 9.1.3. Here is the example, please note the bold ones.&lt;/P&gt;&lt;P&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;&amp;nbsp; array numbers(*) phone1-phone3;&lt;/P&gt;&lt;P&gt;** set sort parameters (hint: would-be macro parms) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; seq&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = 'A' ; * A = ascending, D = descending ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; nodupkey =&amp;nbsp; 1&amp;nbsp; ; * 0 = duplicates allowed, 1 = duplicates not allowed ;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp; if _n_=1 then do;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hash&amp;nbsp; _hh&amp;nbsp; (hashexp: 16, ordered: seq) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dcl hiter _hi&amp;nbsp; ('_hh'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _hh.definekey&amp;nbsp; ('_k', '_n'&amp;nbsp; ) ; * _n - extra enumerating key ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _hh.definedata ('_k'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ; * _k automatically assumes array data type ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _hh.definedone (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) ;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp; end;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;** load composite (_k _n) key on the table&amp;nbsp;&amp;nbsp; ;&lt;/P&gt;&lt;P&gt;** if duplicates to be retained, set 0 &amp;lt;- _n ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _j = lbound (numbers) to hbound (numbers) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _n = _j * ^ nodupkey ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _k = numbers [_j] ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _hh.replace() ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;** use iterator HI to reload array from HH table, now in order ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _n = lbound (numbers) - 1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _rc = _hi.first() by 0 while ( _rc = 0 ) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _n = _n + 1 ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers [_n] = _k ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _rc = _hi.next() ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; _q = _n ;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;** fill array tail with missing values if duplicates are delete ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; do _n = _q + 1 to hbound (numbers) ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers [_n] = . ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; end ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; drop _: ; * drop auxiliary variables ;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp; _hh.clear();&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Haikuo&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 14:48:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96140#M20241</guid>
      <dc:creator>Haikuo</dc:creator>
      <dc:date>2012-08-16T14:48:05Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96141#M20242</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;hi ... another approach (HEX16. maintains values through numeric-character-numeric conversion) ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;data have;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;infile datalines dsd truncover;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;input person $ phone1-phone3;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;datalines;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;A,111,222,111&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;B,,444,444&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;C,111,,222,&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;options missing = ' ';&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;filename d dummy;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;data want;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;file d;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;set have;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;array phone(3);&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;do j=3 to 1 by -1;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp; put (phone:) (hex16. +1) @;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp; if count(_file_ , put(phone(j),hex16.)) ge 2 then phone(j) = .;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp; put;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;end;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;put (phone:) (hex16. +1) @;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;do j=1 to 3; &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp; phone(j) = input(scan(_file_,j,' '),hex16.);&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;end;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;drop j;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;run;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;options missing = '.';&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&lt;BR /&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;results ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="font-family: 'courier new', courier;"&gt;person&amp;nbsp;&amp;nbsp;&amp;nbsp; phone1&amp;nbsp;&amp;nbsp;&amp;nbsp; phone2&amp;nbsp;&amp;nbsp;&amp;nbsp; phone3&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="font-family: 'courier new', courier;"&gt;&amp;nbsp; A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 111&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 222&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="font-family: 'courier new', courier;"&gt;&amp;nbsp; B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 444&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG style="font-family: 'courier new', courier;"&gt;&amp;nbsp; C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 111&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 222&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/STRONG&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 18:32:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96141#M20242</guid>
      <dc:creator>MikeZdeb</dc:creator>
      <dc:date>2012-08-16T18:32:56Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96142#M20243</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;hi Art ... I tried the HASH approach with a lot more observations ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;data have;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;infile datalines dsd truncover;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;input person $ phone1-phone3;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;datalines;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;A,111,222,111&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;B,,444,444&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;C,111,,222,&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;data have;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;set have;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;do _n_=1 to 1000;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&amp;nbsp; output;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;end;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;run;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier;"&gt;&lt;STRONG&gt;&lt;BR /&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;and on my PC it dies after about 3 seconds with the message ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;ERROR: Hash object added 0 items when memory failure occurred.&lt;/P&gt;&lt;P&gt;FATAL: Insufficient memory to execute DATA step program. Aborted during the EXECUTION phase.&lt;/P&gt;&lt;P&gt;ERROR: The SAS System stopped processing this step because of insufficient memory.&lt;/P&gt;&lt;P&gt;NOTE: There were 2543 observations read from the data set WORK.HAVE.&lt;/P&gt;&lt;P&gt;WARNING: The data set WORK.WANT may be incomplete.&amp;nbsp; When this step was stopped there were 2542 observations and 6 variables.&lt;/P&gt;&lt;P&gt;WARNING: Data set WORK.WANT was not replaced because this step was stopped.&lt;/P&gt;&lt;P&gt;NOTE: DATA statement used (Total process time):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; real time&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.07 seconds&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cpu time&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3.04 seconds&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So, what change(s) would make it work with 3,000 observations?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;ps&amp;nbsp; I tried the de-deduping approach that I posted that uses _FILE_ and it took 0.01 seconds with the 3,000 observations.&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;With 30,000 observations and 15 phone numbers, the _FILE_ approach took 0.95 seconds&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 18:59:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96142#M20243</guid>
      <dc:creator>MikeZdeb</dc:creator>
      <dc:date>2012-08-16T18:59:08Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96143#M20244</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;You have a list of phone numbers.&amp;nbsp; Lets assume they are in character format (each length $10), and that you &lt;SPAN style="color: #ff0000;"&gt;don't care if the resulting de-duped phone numbers are in any particular order&lt;/SPAN&gt;.&lt;/P&gt;&lt;P&gt;Then (this is untested):&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;data want (drop=_:);&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array ph {*} $ phone1-phone4;&lt;/P&gt;&lt;P&gt;&amp;nbsp; length _list $60;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do _P=1 to dim(ph);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ph{_P}=' ' then ;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if _list=' ' then _list=ph{_P};&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if index(cats('!',_list,'!'), cats('!',ph{_P},'!') )=0 then _list=catx('!',_list,ph{_P});&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ph{_P}=' ';&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&amp;nbsp; if _list ^=' ' then do _P=1 to countw(_list,'!');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ph{_P}=scan(_list,_P,'!');&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;What this does is scan the list of phone values and lists them, one at a time, in an exclamation-delimited character variable (_LIST).&amp;nbsp; But it only adds a number if it is not already in _LIST (bounding by exclamation mark makes the task of checking for dupes much easier).&amp;nbsp; Then it takes the values in _LIST, and puts them back into the original phone number variables, with dupes removed, and "left-justified".&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;By the way, if the phone values are numeric, you'd only have to change the following (also untested).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array ph {*}&amp;nbsp; phone1-phone4;&amp;nbsp;&amp;nbsp;&amp;nbsp; **drop the $ sign **;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ph{_P}=input(scan(_list,_P,'!'),best10.);&amp;nbsp;&amp;nbsp; ** instead of ph{_P}=scan(_list,_P,'!') **;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 19:35:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96143#M20244</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2012-08-16T19:35:40Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96144#M20245</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;NOTE: Updated code.&amp;nbsp; I think this works, tested it on 40 mil records with 15 phone numbers, and ran in 2.5 minutes.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data want (drop=i j);&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array numbers(*) phone13-phone1;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (lastmiss eq currentmiss);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lastmiss=nmiss(of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; call sortn (of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i=lastmiss+1 to dim(numbers)-1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; skip=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do j=i+1 to dim(numbers);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if numbers(i) eq numbers(j) 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; call missing(numbers(j));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; skip+1;&lt;/P&gt;&lt;P&gt;&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;&amp;nbsp; else 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;&amp;nbsp;&amp;nbsp; i+skip; &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; currentmiss=nmiss(of numbers(*));&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>Thu, 16 Aug 2012 19:48:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96144#M20245</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T19:48:48Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96145#M20246</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;If the maximum possible number of phones (per person) is small enough, then the simplest approach works fastest.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P style="font-family: Consolas, Courier New; font-size: 90%; line-height: 1.1;"&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* test data set */&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;data&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; one; &lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;input&lt;/SPAN&gt;&lt;SPAN&gt; id $ phone1-phone3;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;cards&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; A 111 222 111&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; B&amp;nbsp; . 444 444&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; C 111&amp;nbsp; . 222&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; ;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* dedup phone numbers within a person -- straight-forward approach */&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;%macro&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; missout1(max);&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%local&lt;/SPAN&gt;&lt;SPAN&gt; i j;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%do&lt;/SPAN&gt;&lt;SPAN&gt; i = &amp;amp;&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;max.&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%to&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;2&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%by&lt;/SPAN&gt;&lt;SPAN&gt; -&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;*;&lt;/SPAN&gt;&lt;SPAN&gt;if &lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%do&lt;/SPAN&gt;&lt;SPAN&gt; j = &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%to&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%eval&lt;/SPAN&gt;&lt;SPAN&gt;(&amp;amp;i - &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;);&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%if&lt;/SPAN&gt;&lt;SPAN&gt; &amp;amp;j &amp;gt; &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%then&lt;/SPAN&gt;&lt;SPAN&gt; %&lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;*;&lt;/SPAN&gt;&lt;SPAN&gt; |;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;*;&lt;/SPAN&gt;&lt;SPAN&gt; phone&amp;amp;i = phone&amp;amp;j&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%end&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;*;&lt;/SPAN&gt;&lt;SPAN&gt; then phone&amp;amp;i = &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%end&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;%mend&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp; missout1;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;data&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; chang1;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;set&lt;/SPAN&gt;&lt;SPAN&gt; one;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&lt;/SPAN&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;SPAN&gt;missout1&lt;/SPAN&gt;&lt;/EM&gt;&lt;/STRONG&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;3&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;proc&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;print&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;data&lt;/SPAN&gt;&lt;SPAN&gt;=chang1;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* on lst&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp; Obs&amp;nbsp;&amp;nbsp;&amp;nbsp; id&amp;nbsp;&amp;nbsp;&amp;nbsp; phone1&amp;nbsp;&amp;nbsp;&amp;nbsp; phone2&amp;nbsp;&amp;nbsp;&amp;nbsp; phone3&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp; A&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 111&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 222&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp; B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 444&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp; C&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 111&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 222&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp; */&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* an alternative solution using overlapping definition of&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; arrays -- inspired by Ksharp^s solution using "in" operator,&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; and by Art297^s reversed array definition */&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt; &lt;/SPAN&gt; &lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;&amp;nbsp; %macro&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; missout2(max);&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%local&lt;/SPAN&gt;&lt;SPAN&gt; i j;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%do&lt;/SPAN&gt;&lt;SPAN&gt; i = &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%to&lt;/SPAN&gt;&lt;SPAN&gt; &amp;amp;max;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; array p&amp;amp;&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;i.&lt;/SPAN&gt;&lt;SPAN&gt;&lt;LI&gt; phone&amp;amp;&lt;/LI&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;i.&lt;/SPAN&gt;&lt;SPAN&gt; - phone1;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%end&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%do&lt;/SPAN&gt;&lt;SPAN&gt; i = &amp;amp;max &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%to&lt;/SPAN&gt;&lt;SPAN&gt; 2&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%by&lt;/SPAN&gt;&lt;SPAN&gt; -&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%let&lt;/SPAN&gt;&lt;SPAN&gt; j = &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%eval&lt;/SPAN&gt;&lt;SPAN&gt;(&amp;amp;i - 1);&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if p&amp;amp;i[&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;] in p&amp;amp;&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;j.&lt;/SPAN&gt;&lt;SPAN&gt; then p&amp;amp;i[&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;] = &lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;%end&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;%mend&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp; missout2;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;data&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; chang2;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;set&lt;/SPAN&gt;&lt;SPAN&gt; one;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&lt;/SPAN&gt;&lt;STRONG&gt;&lt;EM&gt;&lt;SPAN&gt;missout2&lt;/SPAN&gt;&lt;/EM&gt;&lt;/STRONG&gt;&lt;SPAN&gt;(&lt;/SPAN&gt;&lt;SPAN style="color: #008080;"&gt;&lt;STRONG&gt;3&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;)&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* check */&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;proc&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;compare&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt; &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;base&lt;/SPAN&gt;&lt;SPAN&gt;=chang1 &lt;/SPAN&gt;&lt;SPAN style="color: #0000ff;"&gt;compare&lt;/SPAN&gt;&lt;SPAN&gt;=chang2;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #000080;"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="color: #008000;"&gt;/* on lst&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp; NOTE: No unequal values were found. All values compared are exactly equal.&lt;/SPAN&gt;&lt;BR /&gt; &lt;SPAN style="color: #008000;"&gt;&amp;nbsp; */&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 22:07:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96145#M20246</guid>
      <dc:creator>chang_y_chung_hotmail_com</dc:creator>
      <dc:date>2012-08-16T22:07:50Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96146#M20247</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Chang,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I still have to update my original post with what I think is correct code, but thought I should first respond to your post.&amp;nbsp; This thread is definitely getting interesting!&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I went a little further than you did.&amp;nbsp; The OP has 40 million records, thus I'm in the middle of running tests on an expansion of a data set that Mike had created offline.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The latest version of my code worked, worked correctly (I think), and only took 2 and 1/2 minutes to run.&amp;nbsp; I'll run the other tests in the morning.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here is the code I tested:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*create a test data set*/&lt;/P&gt;&lt;P&gt;data have (keep=person phone:);&lt;/P&gt;&lt;P&gt;&amp;nbsp; array phone(15);&lt;/P&gt;&lt;P&gt;&amp;nbsp; do person=1 to 40e6;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do j=1 to 15;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; phone(j) = ceil(10*ranuni(999));&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;P&gt;&lt;/P&gt;&lt;P&gt;/*Art's method*/&lt;/P&gt;&lt;P&gt;data want (drop=i j);&lt;/P&gt;&lt;P&gt;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp; array numbers(*) phone15-phone1;&lt;/P&gt;&lt;P&gt;&amp;nbsp; do until (lastmiss eq currentmiss);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; lastmiss=nmiss(of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; call sortn (of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i=lastmiss+1 to dim(numbers)-1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; skip=0;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do j=i+1 to dim(numbers);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if numbers(i) eq numbers(j) 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; call missing(numbers(j));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; skip+1;&lt;/P&gt;&lt;P&gt;&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;&amp;nbsp; else 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;&amp;nbsp;&amp;nbsp; i+skip;&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; currentmiss=nmiss(of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*Chang's method*/&lt;/P&gt;&lt;P&gt;&amp;nbsp; ods _all_ close;&lt;/P&gt;&lt;P&gt;&amp;nbsp; ods listing;&lt;/P&gt;&lt;P&gt;&amp;nbsp; options nocenter cmplib=work.func mprint fullstimer;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; proc fcmp outlib=work.func.rsort;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; subroutine swapn(x, y); /* swaps two numeric vars */&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outargs x, y;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; k = x;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = y;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; y = k;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; endsub;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; subroutine revArray(x&lt;LI&gt;); /* reverse a numeric array or */&lt;/LI&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outargs x;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* swaps x[1] and x[dim(x)]&amp;nbsp;&amp;nbsp; */&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d = dim(x);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x[2] and x[dim(x)-1],&amp;nbsp; */&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do i = 1 to d/2 by 1;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x[3] and x[dim(x)-2],&amp;nbsp; */&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = x&lt;I&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* and so on&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/I&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; n = x[d-i+1];&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; call swapn(m, n);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x&lt;I&gt; = m;&lt;/I&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x[d-i+1] = n;&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; endsub;&lt;/P&gt;&lt;P&gt;&amp;nbsp; quit;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; /* a test data each person can have &amp;amp;max phone numbers */&lt;/P&gt;&lt;P&gt;&amp;nbsp; %let n = %sysevalf(40e6);&amp;nbsp; %*-- number of people&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --*;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %let max = 15;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*-- max number of phones&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --*;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %let p = 0.06;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*-- prob(phone) except for the 1st&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --*;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %let dup = 0.05;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*-- probability of a phone to be duplicated --*;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %let seed = 1234567;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*-- random seed&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; --*;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; /* dedup phone numbers within a person -- straight-forward approach */&lt;/P&gt;&lt;P&gt;&amp;nbsp; %macro missout(max);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %local i j;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %do i = &amp;amp;max. %to 2 %by -1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*;if&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %do j = 1 %to %eval(&amp;amp;i - 1);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %if &amp;amp;j &amp;gt; 1 %then %*; |;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %*; phone&amp;amp;i = phone&amp;amp;j&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;&amp;nbsp;&amp;nbsp; %*; then phone&amp;amp;i = .;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; %end;&lt;/P&gt;&lt;P&gt;&amp;nbsp; %mend&amp;nbsp; missout;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; data chang;&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; %missout(&amp;amp;max.)&lt;/P&gt;&lt;P&gt;&amp;nbsp; run;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 16 Aug 2012 22:58:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96146#M20247</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-16T22:58:20Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96147#M20248</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I thought a quick note was in order to explain why my original alternate code was wrong.&amp;nbsp; It's also a good question, I think, for the certification exam.&amp;nbsp; After all of these years, it wasn't until this afternoon that I understood what was going on with a backwards array assignment.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;For example, take the following one record datastep:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/*create one sample test record*/&lt;/P&gt;&lt;P&gt;data have (keep=person phone:);&lt;/P&gt;&lt;P&gt;&amp;nbsp; input person phone1-phone4;&lt;/P&gt;&lt;P&gt;&amp;nbsp; cards;&lt;/P&gt;&lt;P&gt;1 1 . 3 4&lt;/P&gt;&lt;P&gt;;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Easy enough, but now set it in another datastep, declare an array, and load the phone numbers in reverse order: i.e.,&lt;/P&gt;&lt;P&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;&amp;nbsp; array numbers(*) phone4-phone1;&lt;/P&gt;&lt;P&gt;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp; call sortn (of numbers(*));&lt;/P&gt;&lt;P&gt;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;proc print data=want;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The datastep produces two records, one before, and one after a call sortn.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Can you correctly guess what the output is going to look like?&amp;nbsp; I couldn't, thus based my original code on a faulty understanding.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The actual results:&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Obs&amp;nbsp;&amp;nbsp;&amp;nbsp; person&amp;nbsp;&amp;nbsp;&amp;nbsp; phone1&amp;nbsp;&amp;nbsp;&amp;nbsp; phone2&amp;nbsp;&amp;nbsp;&amp;nbsp; phone3&amp;nbsp;&amp;nbsp;&amp;nbsp; phone4&lt;/P&gt;&lt;P&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 17 Aug 2012 02:59:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96147#M20248</guid>
      <dc:creator>art297</dc:creator>
      <dc:date>2012-08-17T02:59:54Z</dc:date>
    </item>
    <item>
      <title>Re: de-dup array</title>
      <link>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96148#M20249</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Patrick,&lt;/P&gt;&lt;P&gt;For your question, there is no need to use HashTable yet. Since HashTable is a associated arrays. You also can a simple array to get it . I believe my code is very fast . Have a NICE day!&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE&gt;data have;
&amp;nbsp; infile datalines dsd truncover;
&amp;nbsp; input person $ phone1-phone3;
&amp;nbsp; datalines;
A,111,222,111
B,,444,444
C,111,,222,
;
run;
data want(drop=i j k _:);
 set have;
 array _p{*} phone1-phone3 ;
 array _pp{*} _phone1-_phone3;
 j=0;
 do i=1 to dim(_p);
&amp;nbsp; if _p{i} not in _pp then do;j+1;_pp{j}=_p{i};end;
 end;
 do k=1 to dim(_p);
&amp;nbsp; _p{k}=_pp{k};
 end;
run;
&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Ksharp&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 17 Aug 2012 03:44:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/de-dup-array/m-p/96148#M20249</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2012-08-17T03:44:18Z</dc:date>
    </item>
  </channel>
</rss>

