BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
cosmid
Lapis Lazuli | Level 10

Hi,

 

Here are two examples from the SAS Help Center:

 

data u1(keep=x);
   seed=104;
   do i=1 to 5;
      call ranuni(seed, x);
      output;
   end;
   call symputx('seed', seed);
run;
data u2(keep=x);
   seed=&seed;
   do i=1 to 5;
      call ranuni(seed, x);
      output;
   end;
run;

Question 1: The call symputx in the u1, is used for the data step in u2?

 

If I modify the code from u1 to the one below:

data u1(keep=x);
   do seed=1 to 5;
      call ranuni(seed, x);
      output;
   end;
run;

Question 2: Why doesn't the modified code provide 5 different numbers? Each time the seed has a new value, which is like the seed in dataset u2, except it's not a macro variable.

 

Thanks!

 

1 ACCEPTED SOLUTION

Accepted Solutions
antonbcristina
SAS Employee

Hi @cosmid, great question! It's easy to miss this detail in the documentation, but it states under the seed argument that:

 

A new value for seed is returned each time CALL RANUNI is executed.

 

Documentation for CALL RANUNI Routine: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p1iizc7tw29sean1gc3oaoxkbp3r.h....

 

If you run a debugger on your second example, you'll see that in your first iteration of the DO loop seed=1. However, as soon as the CALL RANUNI statement is run, the seed is set to a completely different number that is not within the range of seed values for the DO loop. This causes the DO loop to terminate resulting in only one value.  

View solution in original post

7 REPLIES 7
antonbcristina
SAS Employee

Hi @cosmid, great question! It's easy to miss this detail in the documentation, but it states under the seed argument that:

 

A new value for seed is returned each time CALL RANUNI is executed.

 

Documentation for CALL RANUNI Routine: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p1iizc7tw29sean1gc3oaoxkbp3r.h....

 

If you run a debugger on your second example, you'll see that in your first iteration of the DO loop seed=1. However, as soon as the CALL RANUNI statement is run, the seed is set to a completely different number that is not within the range of seed values for the DO loop. This causes the DO loop to terminate resulting in only one value.  

cosmid
Lapis Lazuli | Level 10
ahh, I did read where it said a new value for seed is returned each time CALL RANUNI is executed but I didn't grasp the meaning of it. Thanks for the explanation!
ballardw
Super User

Second question first:
Why doesn't the modified code provide 5 different numbers? Each time the seed has a new value, which is like the seed in dataset u2, except it's not a macro variable

data u1(keep=x);
   do seed=1 to 5;
      call ranuni(seed, x);
      output;
   end;
run;

 Call ranuni UPDATES the value of seed in that call. So it is very likely returning a value larger than 5 and the loop only executes one time because of the value of the returned value.

You can see what happens with this code:

data work.u1;
   seed=1234;
   do y=1 to 5;
      call ranuni(seed,x);
      output;
   end;
run;

Even though the first time seed is used it has a value of 1234 when the call ranuni executes it will be something quite different when the OUTPUT statement is encountered. When I ran this the output value of seed for the first observation is 523580480.

 

Question 1: The call symputx in the u1, is used for the data step in u2?

 

The Call symputx assigns the value of the seed after the last call ranuni execution to the macro variable seed so that can be used as the initial seed in the second data step.

 

An additional point may be of interest using the following. NOTE the change to the first set keeping the SEED values:

data work.u1(keep=x seed);
   seed=104;
   do i=1 to 5;
      call ranuni(seed, x);
      output;
   end;
   call symputx('seed', seed);
run;
data work.u2(keep=x);
   seed=&seed;
   do i=1 to 5;
      call ranuni(seed, x);
      output;
   end;
run;

data work.u3 (keep=x);
   set work.u1 (firstobs=5);
   do i=1 to 5;
      call ranuni(seed, x);
      output;
   end;
run;

Compare U2 and U3. See anything interesting?

 

 

cosmid
Lapis Lazuli | Level 10

Thank you for that work.u3 example! I now understand that you can use a variable from a dataset as well for the first parameter. And they are using the value from the last seed from work.u1, one is from the CALL SYMPUTX which is used after the DO LOOP and the other is by using the firstobs=5 option. Thanks!

FreelanceReinh
Jade | Level 19

Hi @cosmid,

 

Your questions 1 and 2 have already been answered very well. Let me just add a mathematician's answer to the question in the subject line.

 

The DATA step

data test;
seed=104;
call ranuni(seed,x);
run;

creates the same result as this DATA step:

data test;
seed=104;
seed=mod(seed*397204094, 2**31-1);
x=seed/(2**31-1);
run;

 

Mathematically, the same two formulas work for any other valid, positive seed value (i.e., integer between 1 and 2,147,483,646) as well. Practically, however, the equivalence of the two steps will often break down if the product of the seed and the constant multiplier 397,204,094 exceeds constant('exactint'), which equals 2**53 (=9,007,199,254,740,992) under Windows. For example, with seed=22676507 the results differ slightly (on my Windows workstation) because of a rounding error occurring in the second DATA step. The internal algorithm used by the CALL RANUNI routine avoids rounding errors (and can be emulated in a DATA step with a bit more work).

cosmid
Lapis Lazuli | Level 10
Thanks for the examples! I'm just glad I don't have to explain things mathematiclally to people, lol
sbxkoenk
SAS Super FREQ

Koen

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 7 replies
  • 1228 views
  • 7 likes
  • 5 in conversation