SAS Random Number Generators and Their Uses               n54703.019

     SAS includes a large number of functions.  Among them are
several "random" number generators.  Those that you are most likely
to use are the following:

     RANUNI:  generates random numbers between 0 and 1 which have
              a uniform distribution.

     RANNOR:  generates random numbers with a standard normal [N(0, 1)]
              distribution

     RANBIN:  generates random numbers with a binomial distribution


     Random number generators are useful for carrying out simulation
studies and for generating randomization schedules for clinical trials.
They can also be used in studies which depend on surveys carried out
using random digit dialing.

     We will focus first on the simplest random number generator,
RANUNI.  The following program shows how RANUNI is used:

------------------------------------------------------------------------
options linesize = 80 ;
footnote "~john-c/5421/random.sas &sysdate &systime" ;

data random ;

     seed = 20040427 ;

     n = 10 ;
     do i = 1 to n ;
        x = ranuni(seed) ;
        output ;
     end ;
run ;

proc print data = random ;
title1 'Printout of random numbers generated by RANUNI' ;

------------------------------------------------------------------------

                 Printout of random numbers generated by RANUNI                1
                                                   21:18 Tuesday, April 27, 2004

                     OBS      SEED       N     I       X

                       1    20040427    10     1    0.87825
                       2    20040427    10     2    0.08953
                       3    20040427    10     3    0.81901
                       4    20040427    10     4    0.61657
                       5    20040427    10     5    0.18473
                       6    20040427    10     6    0.97046
                       7    20040427    10     7    0.48202
                       8    20040427    10     8    0.15767
                       9    20040427    10     9    0.54726
                      10    20040427    10    10    0.11800
 
                     ~john-c/5421/random.sas 27APR04 21:18
------------------------------------------------------------------------

     The SEED for the random number generator determines the starting
value.  If you use the same positive SEED in the same program, you
will always get the same results.  In this sense, the results of the
random number generator are not random at all; they are completely
predictable.

     If you start with a different SEED you will get a different sequence of 
random numbers.  However, the same seed used on different occasions will always
give the same sequence.

     However, if SEED is a NEGATIVE number, you will get a different
sequence of numbers every time.  When you use a negative number as
the seed, SAS chooses its own seed which depends on clock time within
the computer.  This has the advantage that the sequence you get is
almost completely impossible to predict.  It has the disadvantage that
if you want the same sequence over again, you may have to wait
several lifetimes to get it.

     Here is one way in which random number generators are used.  Say
you want to generate a randomization schedule for a clinical trial
in which the subjects are supposed to get either a drug or a placebo
with equal probability.  Assume the variable X represents assignment
to either drug or placebo: X = 'D' or X = 'P'.  You generate a random 
number R between 0 and 1 using RANUNI.  If R is less than .5, then
you assign X = 'P'.  If R is greater than or equal to .5, you assign
X = 'D'.  A program which does this is the following:

=======================================================================

options linesize = 80 ;
footnote "~john-c/5421/ransched.sas &sysdate &systime" ;

data ransched ;
     length X $1 ;
     seed = 98694451 ;

     n = 10 ;

     do i = 1 to n ;

        r = ranuni(seed) ;
        if r lt .5 then X = 'P' ;
        if r ge .5 then X = 'D' ;
        output ;

     end ;

 run ;

proc print data = ransched ;
     var seed n i r x ;
title1 'Randomization schedule generated using RANUNI' ;
run ;

------------------------------------------------------------------------
                 Randomization schedule generated using RANUNI                 1
                                                   21:33 Tuesday, April 27, 2004

                  OBS      SEED       N     I       R       X

                    1    98694451    10     1    0.28414    P
                    2    98694451    10     2    0.21248    P
                    3    98694451    10     3    0.38594    P
                    4    98694451    10     4    0.89558    D
                    5    98694451    10     5    0.46266    P
                    6    98694451    10     6    0.90051    D
                    7    98694451    10     7    0.39842    P
                    8    98694451    10     8    0.68491    D
                    9    98694451    10     9    0.07968    P
                   10    98694451    10    10    0.26521    P
 
 
 
                    ~john-c/5421/ransched.sas 27APR04 21:33
=======================================================================

     Note that in this example, the treatment assignments are
unbalanced: there are 6 assignments to placebo P and 4 assignments
to drug D.  This is not an unusual imbalance, but you might want
equal assignments to both groups.

     Here is a way you can guarantee exactly the same number of
assignments to each group, using the random number generator:

     1.  Number 10 cards from 1 to 10: put the number in a circle
         on each card.

     2.  Write a random number on each card.

     3.  Sort the cards in order by the random numbers.

     4.  Assign the first 5 cards to placebo and the second 5
         cards to drug.  Write the treatment assignment on the
         cards.

     5.  Sort the cards again into the original order.  You now
         have a random sequence of assignments to drug and placebo
         of length 10, with exactly 5 assignments in each group.

     Here is a SAS program, using RANUNI, which accomplishes the same
thing:

=======================================================================


options linesize = 80 ;
footnote "~john-c/5421/rancards.sas &sysdate &systime" ;

data rancards ;
     n = 10 ;
     seed = 20010101 ;

     do i = 1 to 10 ;
        r = ranuni(seed) ;
        output ;
     end ;

run ;

proc print data = rancards ;
     var n seed i r ;
title1 'Sequence of 10 random numbers generated by RANUNI.' ;

proc sort data = rancards ;
     by r ;

proc print data = rancards ;
     var n seed i r ;
title1 'Sequence of 10 random numbers sorted in ascending order' ;

data rancards ;
     retain ncard 0 ;
     set rancards ;
     ncard = ncard + 1 ;
     X = 'P' ;
     if ncard ge 6 then X = 'D' ;
run ;

proc print data = rancards ;
     var n seed i r x ;
title1 'Treatment assignments ... by ncard.' ;

proc sort data = rancards ;
     by i ;

proc print data = rancards ;
     var n seed i r x ;
title1 'Balanced randomization schedule ...' ;

------------------------------------------------------------------------
               Sequence of 10 random numbers generated by RANUNI.              1
                                                   21:57 Tuesday, April 27, 2004

                     OBS     N      SEED       I       R

                       1    10    20010101     1    0.70336
                       2    10    20010101     2    0.17914
                       3    10    20010101     3    0.74710
                       4    10    20010101     4    0.09325
                       5    10    20010101     5    0.66496
                       6    10    20010101     6    0.66555
                       7    10    20010101     7    0.09562
                       8    10    20010101     8    0.07448
                       9    10    20010101     9    0.49362
                      10    10    20010101    10    0.42075
 
 
                    ~john-c/5421/rancards.sas 27APR04 21:57
------------------------------------------------------------------------
             Sequence of 10 random numbers sorted in ascending order            2
                                                   21:57 Tuesday, April 27, 2004

                     OBS     N      SEED       I       R

                       1    10    20010101     8    0.07448
                       2    10    20010101     4    0.09325
                       3    10    20010101     7    0.09562
                       4    10    20010101     2    0.17914
                       5    10    20010101    10    0.42075
                       6    10    20010101     9    0.49362
                       7    10    20010101     5    0.66496
                       8    10    20010101     6    0.66555
                       9    10    20010101     1    0.70336
                      10    10    20010101     3    0.74710
 
                    ~john-c/5421/rancards.sas 27APR04 21:57
------------------------------------------------------------------------
                       Treatment assignments ... by ncard.                      3
                                                   21:57 Tuesday, April 27, 2004

                  OBS     N      SEED       I       R       X

                    1    10    20010101     8    0.07448    P
                    2    10    20010101     4    0.09325    P
                    3    10    20010101     7    0.09562    P
                    4    10    20010101     2    0.17914    P
                    5    10    20010101    10    0.42075    P
                    6    10    20010101     9    0.49362    D
                    7    10    20010101     5    0.66496    D
                    8    10    20010101     6    0.66555    D
                    9    10    20010101     1    0.70336    D
                   10    10    20010101     3    0.74710    D
 
                    ~john-c/5421/rancards.sas 27APR04 21:57
------------------------------------------------------------------------
                       Balanced randomization schedule ...                      4
                                                   21:57 Tuesday, April 27, 2004

                  OBS     N      SEED       I       R       X

                    1    10    20010101     1    0.70336    D
                    2    10    20010101     2    0.17914    P
                    3    10    20010101     3    0.74710    D
                    4    10    20010101     4    0.09325    P
                    5    10    20010101     5    0.66496    D
                    6    10    20010101     6    0.66555    D
                    7    10    20010101     7    0.09562    P
                    8    10    20010101     8    0.07448    P
                    9    10    20010101     9    0.49362    D
                   10    10    20010101    10    0.42075    P
 
                    ~john-c/5421/rancards.sas 27APR04 21:57
=======================================================================

RANNOR:

     RANNOR is another SAS pseudo-random number generator which produces
observations which have a normal distribution with mean 0 and standard
deviation 1.  RANNOR is used in much the same way as RANUNI:

     1.  Specify a seed, usually a large positive number

     2.  r = rannor(seed) ;

     If you specify a negative seed, RANNOR will generate a sequence of
based on the computer's internal clock - that is, every time you run the 
program you will get a different sequence.

     If you want observations from a normal distribution with mean -2 and
standard deviation 10, do the following:

         r = -2 + 10*rannor(seed) ;

     A random number generator sequence will be re-started if it is run in a new
data step.

     It is possible to re-start a random number sequence with a new seed within
a given data step by the use of a 'CALL' statement, as in the following program:

========================================================================

options linesize = 80 ;
footnote "~john-c/5421/ranseq.sas &sysdate &systime" ;

data ranseq1 ;

     seed = 987654321 ;

     do i = 1 to 10 ;
        r = rannor(seed) ;
        output ;
     end ;

run ;

data ranseq2 ;

     seed = 20040501 ;

     do i = 1 to 10 ;
        r = rannor(seed) ;
        output ;
     end ;

run ;

data ranseq3 ;

     seed = 987654321 ;

     i = 1 ;
     call rannor(seed, r) ;
     output ;

     do i = 2 to 20 ;
        r = rannor(seed) ;
        output ;
     end ;

run ;

data ranseq4 ;

     seed = 20040501 ;

     i = 1 ;
     call rannor(seed, r) ;
     output ;

     do i = 2 to 10 ;
        r = rannor(seed) ;
        output ;
     end ;

     seed = 987654321 ;

     i = 1 ;
     call rannor(seed, r) ;
     output ;

     do i = 2 to 10 ;
        r = rannor(seed) ;
        output ;
     end ;

     seed = 20040501 ;

     i = 1 ;
     call rannor(seed, r) ;
     output ;

     do i = 2 to 10 ;
        r = rannor(seed) ;
        output ;
     end ;

run ;

proc print data = ranseq1 ;
title1 'Printout of dataset ranseq1' ;
run ;

proc print data = ranseq2 ;
title1 'Printout of dataset ranseq2' ;
run ;

proc print data = ranseq3 ;
title1 'Printout of dataset ranseq3' ;
run ;

proc print data = ranseq4 ;
title1 'Printout of dataset ranseq4' ;
run ;

endsas ;
------------------------------------------------------------------------

                          Printout of dataset ranseq1                          1
                                                     14:25 Saturday, May 1, 2004

                       OBS       SEED       I        R

                         1    987654321     1     0.15558
                         2    987654321     2     1.07101
                         3    987654321     3    -0.20140
                         4    987654321     4    -1.04728
                         5    987654321     5    -0.86722
                         6    987654321     6     0.53976
                         7    987654321     7    -0.84926
                         8    987654321     8     1.10120
                         9    987654321     9     0.60952
                        10    987654321    10    -0.24234
 
 
                     ~john-c/5421/ranseq.sas 01MAY04 14:25
------------------------------------------------------------------------

                           Printout of dataset ranseq2                          2
                                                     14:25 Saturday, May 1, 2004

                       OBS      SEED       I        R

                         1    20040501     1     0.76021
                         2    20040501     2     0.51044
                         3    20040501     3    -0.45282
                         4    20040501     4    -0.90734
                         5    20040501     5     1.64467
                         6    20040501     6    -0.24150
                         7    20040501     7    -0.97785
                         8    20040501     8     0.96686
                         9    20040501     9    -0.58720
                        10    20040501    10     1.03371
 
 
                     ~john-c/5421/ranseq.sas 01MAY04 14:25
------------------------------------------------------------------------

                           Printout of dataset ranseq3                          3
                                                     14:25 Saturday, May 1, 2004

                      OBS       SEED        I        R

                        1    1645322396     1     0.15558
                        2    1645322396     2     1.07101
                        3    1645322396     3    -0.20140
                        4    1645322396     4    -1.04728
                        5    1645322396     5    -0.86722
                        6    1645322396     6     0.53976
                        7    1645322396     7    -0.84926
                        8    1645322396     8     1.10120
                        9    1645322396     9     0.60952
                       10    1645322396    10    -0.24234
                       11    1645322396    11     0.52420
                       12    1645322396    12    -0.38888
                       13    1645322396    13     2.95714
                       14    1645322396    14    -1.31965
                       15    1645322396    15     0.31193
                       16    1645322396    16     0.37487
                       17    1645322396    17     0.36149
                       18    1645322396    18    -0.86003
                       19    1645322396    19    -1.33057
                       20    1645322396    20     0.64818
 
 
                     ~john-c/5421/ranseq.sas 01MAY04 14:25
------------------------------------------------------------------------

                           Printout of dataset ranseq4                          4
                                                     14:25 Saturday, May 1, 2004

                      OBS       SEED        I        R

                        1    1881399392     1     0.76021
                        2    1881399392     2     0.51044
                        3    1881399392     3    -0.45282
                        4    1881399392     4    -0.90734
                        5    1881399392     5     1.64467
                        6    1881399392     6    -0.24150
                        7    1881399392     7    -0.97785
                        8    1881399392     8     0.96686
                        9    1881399392     9    -0.58720
                       10    1881399392    10     1.03371
                       11    1645322396     1     0.15558
                       12    1645322396     2    -0.72313
                       13    1645322396     3     1.06559
                       14    1645322396     4    -1.56206
                       15    1645322396     5    -0.05762
                       16    1645322396     6     0.29086
                       17    1645322396     7    -1.03002
                       18    1645322396     8    -0.06367
                       19    1645322396     9    -0.00630
                       20    1645322396    10    -1.06905
                       21    1881399392     1     0.76021
                       22    1881399392     2     0.12988
                       23    1881399392     3    -0.67515
                       24    1881399392     4     0.11125
                       25    1881399392     5    -0.56765
                       26    1881399392     6    -0.25198
                       27    1881399392     7    -1.10058
                       28    1881399392     8    -2.29427
                       29    1881399392     9    -0.18066
                       30    1881399392    10     0.67819
 
                     ~john-c/5421/ranseq.sas 01MAY04 14:25
========================================================================

     Note that when the 'CALL' form of the random number generator is used,
the seed is changed and the seed that is printed out is not the same as the
seed which was given to the function in the first place.

========================================================================
n54703.019  Last update: May 1, 2004.