Using SYSRANDOM and SYSRANEND Macro Variables to Produce Random Number Streams

Overview of the SYSRANDOM and SYSRANEND Macro Variables

Many SAS procedures (for example, FREQ, GLM, MCMC, OPTEX, and PLAN) use random number streams. These procedures use the same random number functions and CALL routines that you use in SAS DATA steps. SAS procedures use a SEED= option to provide the seed that initializes the random number stream.
SAS procedures with random number seeds create two macro variables, SYSRANDOM and SYSRANEND. You can use these macro variables to produce reproducible random number streams across procedures.

The SYSRANDOM Macro Variable

The SYSRANDOM macro variable stores the random number seed from the most recent procedure. The macro variable corresponds to the integer that is specified in the SEED= option. Many procedures, such as FREQ, GLM, MI, MCMC, OPTEX, PHREG, and PLAN, have a SEED= option. The SEED= option specifies the integer that is used to start the random number stream. Positive seed specifications are used as specified. If a seed is not specified in the SEED= option, or if the seed is less than or equal to zero, the procedure generates a seed from the clock time. You can use the SYSRANDOM macro variable to recover both directly specified and internally generated seeds.

The SYSRANEND Macro Variable

The SYSRANEND macro variable stores a seed that can be used to start the next step in your program. In some cases, this seed captures the state of the random number process when a procedure is completed. Your program can contain multiple steps and can control the random number sequence without specifying an explicit seed for each procedure. You can start the simulation with one seed, and use the SYSRANEND macro variable to provide the seed in all subsequent procedures. In some cases, you can also use the SYSRANEND macro variable to stop and restart the random number generators (RNGs) that are continuing the same stream.
There are two types of RNGs in SAS procedures. The older RNG, which is used by the RANUNI function, starts the pseudo-random number stream with a single seed, and the state of the process can be captured in a new seed. The GLM, GLIMMIX, MI, OPTEX, PLAN, and other procedures use this older RNG. When the procedure exits, the value that is stored in SYSRANEND is the new seed. You can stop and restart the generator from its stopping point by using the SYSRANEND macro variable.
Other procedures, such as MCMC, GENMOD, LIFEREG, and PHREG, use the newer Mersenne-Twister RNG. This RNG is also used in the RAND function and does not propagate the state of the stream through a single seed. Some procedures use one RNG for some computations and the other RNG for other computations. You can use the SYSRANEND macro variable from these procedures to make a sequence of procedure runs reproducible, but the random streams will not be equal to that of a single, long, procedure run.

Example: Reproducing Results

The following example shows how to recover the seed and use it to reproduce a set of results. The MCMC procedure generates samples from a posterior distribution. The following statements produce posterior samples from a linear regression model:
title 'Bayesian Linear Regression';

proc mcmc data=sashelp.class seed=0 outpost=out1;
   parms beta0 0 beta1 0;
   prior beta0 beta1 ~ normal(mean=0, var=1e6);
   mu=beta0 + beta1*height;
   model weight ~ n(mu, var=137);
run;
Because SEED=0 was specified, a random number seed is automatically generated from the clock time. This seed is stored in the SYSRANDOM macro variable. You can use a %PUT statement to display its value:
%put sysrandom=&sysrandom;
The following step creates the same results as the previous step by using the same seed:
proc mcmc data=sashelp.class seed=&sysrandom outpost=out2;
   parms beta0 0 beta1 0;
   prior beta0 beta1 ~ normal(mean=0, var=1e6);
   mu=beta0 + beta1*height;
   model weight ~ n(mu, var=137);
run;
You can submit the following step to see that the two PROC MCMC executions produce identical samples:
proc compare data=out1 compare=out2;
run;

Example: Creating a Reproducible Random Number Stream

The PLAN procedure constructs and randomizes full factorial experimental designs. The OPTEX procedure searches a set of candidate design points for an optimal experimental design. Both procedures have a SEED= option. You can use the SYSRANEND macro variable to make a sequence of steps reproducible, as shown in the following example:
proc plan seed=17;
   factors x1=4 x2=4 x3=2 x4=2 x5=3 x6=3 x7=2 x8=2 / noprint;
   output out=cand;
run;
quit;

%put sysranend=&sysranend;

proc optex data=cand seed=&sysranend;
   class x1-x8;
   model x1-x8;
   generate n=26 iter=10 method=m_federov;
   output out=des;
run;
quit;
You can call PROC OPTEX multiple times and stop when a design with an efficiency (the measure of how good the design is) greater than 98% is found. You can use the SYSRANDOM and SYSRANEND macro variables to do this. The following statements call PROC OPTEX to create 100 designs and output the best D-efficiency:
proc plan seed=17;
   factors x1=4 x2=4 x3=2 x4=2 x5=3 x6=3 x7=2 x8=2 / noprint;
   output out=cand;
run;
quit;

%macro design;
   ods listing close;
   %do %until(%sysevalf(&eff > 98));
      proc optex data=Cand seed=&sysranend;
         class x1-x8;
         model x1-x8;
         generate n=26 iter=100 keep=1 method=m_federov;
         ods output efficiencies=e1;
      run;
      quit;
  
      data _null_;
         set e1;
         call symputx('eff', dcriterion, 'L');
      run;
      %end;
   ods listing;

   proc optex data=Cand seed=&sysrandom;
      class x1-x8;
      model x1-x8;
      generate n=26 iter=100 keep=1 method=m_federov;
      output out=des;
   run;
   quit;
%mend;

%design;   
The D-efficiency is stored in a macro variable, and iteration stops when D-efficiency is greater than 98. The seed from the last step is used to reproduce and display the final results.