BookmarkSubscribeRSS Feed
Bwheck
Calcite | Level 5

Hello SAS Community,

I am working on a program where I have groups of independent variables and these groups of variables need to be assigned randomly (without replacement) so that each group"number" gets randomly assigned to a group "letter" in each iteration. So, the piece of code would look something like:

%let mgroupa= mfemale mage;

%let mgroupb= mmarried mprevmar mchildre mchld617;

%let mgroupc= mhsgrad msomcol mcollege mgradsch;

%let mgroupd= minc1015 minc1520 minc2025 minc2530 minc3035 minc3540

              minc4050 minc5060 minc6075 mincgt75;

%let mgroupe= mmidatla mencent mwncent msatlan mescent mwscent mmountai mpacific;

%let mgroupf= mnotcc mnotmsa mnotid;

* rename white variables;

%let wgroupa= wfemale wage;

%let wgroupb= wmarried wprevmar wchildre wchld617;

%let wgroupc= whsgrad wsomcol wcollege wgradsch;

%let wgroupd= winc1015 winc1520 winc2025 winc2530 winc3035 winc3540

              winc4050 winc5060 winc6075 wincgt75;

%let wgroupe= wmidatla wencent wwncent wsatlan wescent wwscent wmountai wpacific;

%let wgroupf= wnotcc wnotmsa wnotid;

%let mgroup1 = &mgroupf;

  %let mgroup2 = &mgroupa;

  %let mgroup3 = &mgroupb;

  %let mgroup4 = &mgroupc;

  %let mgroup5 = &mgroupd;

  %let mgroup6 = &mgroupe;

  %let wgroup1 = &wgroupf;

  %let wgroup2 = &wgroupa;

  %let wgroup3 = &wgroupb;

  %let wgroup4 = &wgroupc;

  %let wgroup5 = &wgroupd;

  %let wgroup6 = &wgroupe;

    * define distribution switches as arrays;

    array x0a(&k) &wgroup1 &wgroup2 &wgroup3 &wgroup4 &wgroup5 &wgroup6;

    array x1a(&k) &mgroup1 &wgroup2 &wgroup3 &wgroup4 &wgroup5 &wgroup6;

    array x2a(&k) &mgroup1 &mgroup2 &wgroup3 &wgroup4 &wgroup5 &wgroup6;

    array x3a(&k) &mgroup1 &mgroup2 &mgroup3 &wgroup4 &wgroup5 &wgroup6;

    array x4a(&k) &mgroup1 &mgroup2 &mgroup3 &mgroup4 &wgroup5 &wgroup6;

    array x5a(&k) &mgroup1 &mgroup2 &mgroup3 &mgroup4 &mgroup5 &wgroup6;

    array x6a(&k) &mgroup1 &mgroup2 &mgroup3 &mgroup4 &mgroup5 &mgroup6;

The difference in what I want however is that in each iteration of a loop, mgroup1-mgroup6 and wgroup1-wgroup6 would be assigned randomly to mgroupa,mgroupb,mgroupc,mgroupd,mgroupe, or mgroupf, without replacement in each iteration. Any ideas on how I could achieve this?

Thanks so much for any help you can provide!

8 REPLIES 8
art297
Opal | Level 21

I'm not exactly sure what you are trying to do, and you could probably do something with proc surveyselect, but thought you might be able to incorporate something similar to the following.  The purpose of the following code, stolen from a sasCommunity.org article by Paul Dorfman, sorts one array according to its values and rearranges a second array according to the same order:

%macro combsort (arr1 =, arr2=, order= <);

  drop __:;

  do __g = hbound (&arr1) - 1 by 0 while (__s or __g > 1);

    __g = int (__g / 1.3);

    if __g in (0 ) then __g = 1;

    else if __g in (9, 10) then __g = 11;

    __s = 0;

    do __j = lbound (&arr1) to hbound (&arr1) - __g;

      __k = __j + __g;

      if &arr1[__j] &order &arr1[__k] then continue;

      __t = &arr1[__j];

      &arr1[__j] = &arr1[__k];

      &arr1[__k] = __t;

      __tt = &arr2[__j];

      &arr2[__j] = &arr2[__k];

      &arr2[__k] = __tt;

      __s = 1;

    end;

  end;

%mend;

%let n=5;

data want;

  array values(&n.) $ ('a','b','c','d','e');

  array order(&n.) _temporary_;

  do _n_=1 to &n.;

    order(_n_)=ranuni(0);

  end;

  %combsort(arr1=order, arr2=values);

run;

Bwheck
Calcite | Level 5

Hello Arthur,

I am not sure if this is exactly what I need, but I will look at it, thanks for your suggestion. Let me try to rephrase the question in a way that is more comprehensible:

Suppose I have code as follows:

%let groupa = a

%let groupb = b

%let groupc = c

group1 = &groupa;

group2 = &groupb;

group3 = &groupc;

Except what I want is that on each iteration of a larger loop, group1, group2, and group3 are randomly assigned to groupa, groupb, or groupc on each iteration (without replacement). So, perhaps the next iteration is then

group1 = &groupc;

group2 = &groupa;

group3 = &groupb

etc..

Hopefully that is more clear, thanks so much for your time!;

SteveDenham
Jade | Level 19

This really looks like PROC PLAN territory.  The first example in getting started randomizes four levels of drug to three replicates.  Here, I believe you have three levels, and it looks like 6 replicates (although that is not truly clear to me).  Could you run PROC PLAN, get an output dataset, and then put the results into the arrays?

Steve Denham

Bwheck
Calcite | Level 5

Hello all,

Someone on the stack overflow forums gave me this answer:

data rand;

do i=1 to 3;

   r =ranuni(0);

   output;

end;

run;

proc sort data=rand;

  by r;

run;

data junk;

  set rand;

  format group $6.;

  group = catt("group",i);

  if _n_ = 1 then

    call symput(group,"&groupa");

  else if _n_ = 2 then

    call symput(group,"&groupb");

  else

    call symput(group,"&groupc");

run;

%put group1: &group1;

%put group2: &group2;

%put group3: &group3;

This code does exactly the randomization that I was looking for. Thanks for all of your time and suggestions!

art297
Opal | Level 21

The code you posted doesn't run.  I tried it because I was interested in discovering what you were really looking for.

Bwheck
Calcite | Level 5

Hmm I am not sure, it runs fine for me. The only thing is that it gives warnings because groupa, groupb, and groupc have not been initialized.

art297
Opal | Level 21

That "small" problem is not a small problem.

The code assigns three random numbers to a variable called r in 3 records having values of i of 1, 2 and 3.  It then sorts those records according to the values of r.

The 3rd part of the code is simply wrong!  It incorrectly tries to apply the values of non-existing macro variables to one variable.  I have no idea what was actually intended.

If all you needed was one iteration, then you could just stop after the 2nd part of the stack overflow proposed code.  My understanding was that you needed multiple iterations of that same process.

Bwheck
Calcite | Level 5

Hello Arthur,

Yes, you are correct that in order for this snippet of code to make sense, we should define the groupa, b, and c macros, which of course I did in my own program but just left out here.

Also yes, this of course only performs one iteration whereas I was asking for multiple iterations. I am still working on exactly how to implement it in my code, but I inserted this snippet into a large macro do-loop in my code, and this snippet will randomly assign the groups in each iteration.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 801 views
  • 0 likes
  • 3 in conversation