<?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 Create unique, random identifiers in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/935997#M367944</link>
    <description>&lt;P&gt;Hello,&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am attempting to create a &lt;STRONG&gt;unique&lt;/STRONG&gt;, random ID variable for all existing IDs within dataset y. I have played around with a bunch of code however, I get a few duplicate IDs each time. How do I transform the below code to produce a unique, random number between 1 and 10**8? I have used streaminit(1) to ensure the same random numbers are generated on each run.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Data x;&lt;/P&gt;&lt;P&gt;Set y;&lt;/P&gt;&lt;P&gt;Call streaminit(1);&lt;BR /&gt;ID = RAND('Integer',(10 ** 8));&lt;/P&gt;&lt;P&gt;Run;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you in advance,&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 17 Jul 2024 07:08:45 GMT</pubDate>
    <dc:creator>ALEXIA1</dc:creator>
    <dc:date>2024-07-17T07:08:45Z</dc:date>
    <item>
      <title>Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/935997#M367944</link>
      <description>&lt;P&gt;Hello,&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am attempting to create a &lt;STRONG&gt;unique&lt;/STRONG&gt;, random ID variable for all existing IDs within dataset y. I have played around with a bunch of code however, I get a few duplicate IDs each time. How do I transform the below code to produce a unique, random number between 1 and 10**8? I have used streaminit(1) to ensure the same random numbers are generated on each run.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Data x;&lt;/P&gt;&lt;P&gt;Set y;&lt;/P&gt;&lt;P&gt;Call streaminit(1);&lt;BR /&gt;ID = RAND('Integer',(10 ** 8));&lt;/P&gt;&lt;P&gt;Run;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you in advance,&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 17 Jul 2024 07:08:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/935997#M367944</guid>
      <dc:creator>ALEXIA1</dc:creator>
      <dc:date>2024-07-17T07:08:45Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936000#M367946</link>
      <description>&lt;P&gt;You could try PROC SURVEYSELECT:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
 set sashelp.class;
run;




data id;
do id=1 to 10**8;
 output;
end;
run;
%let dsid=%sysfunc(open(have));
%let nobs=%sysfunc(attrn(&amp;amp;dsid.,nlobs));
%let dsid=%sysfunc(close(&amp;amp;dsid.));
proc surveyselect data=id out=id2 seed=123 noprint sampsize=&amp;amp;nobs. outrandom;
run;
data want;
 merge have id2;
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 17 Jul 2024 07:38:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936000#M367946</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-07-17T07:38:02Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936001#M367947</link>
      <description>&lt;P&gt;Here is another way:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;Data x;
if _n_=1 then do;
 length id 8;
 declare hash h(hashexp:20);
 h.definekey(key:'id');
 h.definedone();
end;
Set sashelp.class;

Call streaminit(1);
do until(rc ne 0);
  ID = RAND('Integer',1,10**8);
  rc=h.check();
end;
h.add();
drop rc;
Run; &lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 17 Jul 2024 08:05:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936001#M367947</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2024-07-17T08:05:38Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936004#M367949</link>
      <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/408661"&gt;@ALEXIA1&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If your new IDs just need to "look like" random numbers, you can also resort to the (deprecated) &lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p1fkiqt9ygapyxn1pd1w8manlpub.htm" target="_blank" rel="noopener"&gt;RANUNI function&lt;/A&gt;, which creates up to 2,147,483,646&amp;nbsp;&lt;EM&gt;unique&lt;/EM&gt; pseudo-random&amp;nbsp; numbers by default:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data x;
set y;
do until(ID &amp;lt;= 1e8);
  ID = ranuni(2718)*(2**31-1);
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 17 Jul 2024 09:11:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936004#M367949</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2024-07-17T09:11:17Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936014#M367956</link>
      <description>&lt;P&gt;Is there already an ID variable in the dataset which you want to mask with the new random ID? If yes,&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp&lt;/a&gt;&amp;nbsp;'s code needs to be expanded to take care of possible duplicate entries of the already existing ID.&lt;/P&gt;</description>
      <pubDate>Wed, 17 Jul 2024 11:34:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936014#M367956</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2024-07-17T11:34:14Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936040#M367963</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Is there already an ID variable in the dataset which you want to mask with the new random ID? If yes,&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp&lt;/a&gt;&amp;nbsp;'s code needs to be expanded to take care of possible duplicate entries of the already existing ID.&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Good point from&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;. In the case of an existing ID in the same range (1, 2, ..., 10**8) the RANUNI approach is particularly simple thanks to the &lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p1iizc7tw29sean1gc3oaoxkbp3r.htm" target="_blank" rel="noopener"&gt;CALL RANUNI routine&lt;/A&gt;, which can &lt;EM&gt;compute&lt;/EM&gt; the new ID from the old one:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Create sample data for demonstration */

data have;
input ID othervar $;
cards;
 12345678 A1
 11111111 B1
100000000 C1
        1 D1
 87654321 E1
 12345678 A2
 11111111 B2
100000000 C2
        1 D2
 87654321 E2
;

/* Create unique pseudo-random identifier ID2 between 1 and 10**8 for each existing ID in the same range */

data want;
set have;
ID2=ID;
do until(ID2&amp;lt;=1e8);
  call ranuni(ID2, _n_);
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Result:&lt;/P&gt;
&lt;PRE&gt;Obs           ID    othervar       ID2

  1     12345678       A1       69598248
  2     11111111       B1       13830595
  3    100000000       C1       60730215
  4            1       D1       48774337
  5     87654321       E1        2209083
  6     12345678       A2       69598248
  7     11111111       B2       13830595
  8    100000000       C2       60730215
  9            1       D2       48774337
 10     87654321       E2        2209083&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Edit:&lt;/U&gt; Moreover, you can compute ("reconstruct") the original ID from the new ID2. There is no SAS-supplied function or CALL routine for that, but the necessary calculations can be done in a DATA step:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Reconstruct the original ID from the new ID2 */

%let c=58743242 ; /* multiplicative inverse of the "multiplier" 397204094 found in RANUNI documentation, modulo 2**31-1 */
%let d=%sysevalf(2**31-1); /* =2147483647 */

data check(drop=_:);
/* Preparation: compute 10**k * 58743242 modulo 2**31-1, k=1, ..., 9 */
array _a[9] _temporary_;
if _n_=1 then do;
  _a[1]=mod(10*&amp;amp;c, &amp;amp;d);
  do _k=2 to 9;
    _a[_k]=mod(10*_a[_k-1], &amp;amp;d);
  end;
end;
set want;
_m=ID2;
do until(orig_ID&amp;lt;=1e8);
  _t=put(_m,10.);
  _s=input(char(_t,10), 1.)*&amp;amp;c;
  do _k=1 to length(left(_t))-1;
    _s+input(char(_t,10-_k), 1.)*_a[_k];
  end;
  orig_ID=mod(_s,&amp;amp;d);
  _m=orig_ID;
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 17 Jul 2024 13:49:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936040#M367963</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2024-07-17T13:49:53Z</dc:date>
    </item>
    <item>
      <title>Re: Create unique, random identifiers</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936121#M367987</link>
      <description>&lt;P&gt;Here's a program that leverages the hash approach suggested by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp&lt;/a&gt;&amp;nbsp;.&amp;nbsp; It assumes there is an old ID variable, and also that multiple observations can have the same old ID value, and therefore should be assigned the same randomly determined NEWID value.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It creates dataset WANT with the NEWID (but not the old ID), and a second dataset LOOKUP with all the ID/NEWID pairs:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop=id);  /*But keep NEWID*/

  set have  end=end_of_have;

  if _n_=1 then do;
    declare hash LNK (ordered:'A');
      LNK.definekey('id');
      LNK.definedata('id','newid');
      LNK.definedone();
    declare hash NEW ();
      NEW.definekey('newid');
      NEW.definedone();
  end;

  call streaminit(20240717);
  if LNK.find()^=0 then do;
    do until (NEW.check()^=0);
      newID = RAND('Integer',(10 ** 8));
    end;
    NEW.add();
    LNK.add();
  end;

  if end_of_have then LNK.output(dataset:'lookup');
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Since the LOOKUP dataset is a 1:1 pairing, it can be used to find NEWID for each ID, ... and the reverse.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In the case of very large cardinality of the old ID variable.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;This also assumes that you have no more than 10**8 unique old ID values.&lt;/LI&gt;
&lt;LI&gt;The closer the cardinality of your old ID gets to 10**8, the slower this process will be.&lt;/LI&gt;
&lt;LI&gt;And the greater risk there will be that the hash object will require more memory than available.&lt;/LI&gt;
&lt;/OL&gt;</description>
      <pubDate>Thu, 18 Jul 2024 03:48:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Create-unique-random-identifiers/m-p/936121#M367987</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-07-18T03:48:48Z</dc:date>
    </item>
  </channel>
</rss>

