turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- General Programming
- /
- Randomizing variable groups in arrays

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

12-20-2013 09:46 PM

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!

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Bwheck

12-21-2013 09:29 AM

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;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

12-21-2013 01:07 PM

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!;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Bwheck

12-23-2013 08:16 AM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Bwheck

12-26-2013 05:59 PM

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!

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Bwheck

12-26-2013 06:12 PM

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

12-26-2013 08:02 PM

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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Bwheck

12-26-2013 08:23 PM

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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

12-26-2013 10:53 PM

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.