BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
DJ20
Obsidian | Level 7

Hi everyone,

 

I am working on SAS/IML. I am trying to figure out the number of combinations of factors in factorial design as follows :

 

imagine we have 4 factors, A, B, C and D. I want to get the following:

 

1

A

B

AB

C

AC

BC

ABC

D

AD

BD

ABD

CD

ACD

BCD

ABCD

 

Basically the first four combinations (1, A, B, AB) are always the same for any number of factors (m) so I have put this in a matrix form as initial combinations:

 

ncomb = 2**(m);
print ncomb;
initial_combs = j(4,m,0);
initial_combs[2,1] = 1;
initial_combs[3,2] = 1;
initial_combs[4,1] = 1;
initial_combs[4,2] = 1;
print initial_combs;

 

I have used 0's and 1's to indicate the absence and presence of the factor respectively.

 

The I used the initial_comb matrix to add the following four combinations (C, AC, BC, ABC). All I have done is adding C to the initial combinations:

 

combs = j(4,m,0);
count = 3;
do i = 1 to 4;
do j = 1 to m;
if initial_combs[i,j] = 1
then combs[i,j] = initial_combs[i,j];
else combs[i,count] = 1;
end;
end;
combs = initial_combs // combs;
print combs;

 

Note; I have combined the initial_combs matrix with the new combs. If I had 3 factors I would stop here. As I had 4 factors I have to do another set of calculations:

 

combss = j(8,m,0);
count = 4;
do i = 1 to 8;
do j = 1 to m;
if combs[i,j] = 1
then combss[i,j] = combs[i,j];
else combss[i,count] = 1;
end;
end;
combss = combs // combss;
print combss;

 

In the last set, I have used the previous combined matrix (initial_combs with the new combs) and added D to the existing combinations. Again I had to combine the previous combinations (combs) with the new one (combss) to get the full set of combinations for m=4.

 

 

If I want to work out the combinations for m=5 I have to add another set of calculations.

 

Basically this will make the program very long. I need to combine all these separate sets of calculations into one loop maybe. The loop should depend on the number of factor (3, 4, 5,.....) I have tried to figure out how to do it but I couldn't. It is greatly appreciated if anyone could help 

 

Thanks,

DJ

 

1 ACCEPTED SOLUTION

Accepted Solutions
IanWakeling
Barite | Level 11

If the order of the rows of the matrix is not important then the problem is equivalent to counting in binary.   For example

 

proc iml;

start FullFactorial( n );
  r = 2 ## n;
  x = j(r, n);
  pot = 2 ## ( (n-1):0 );
  do i = 1 to r;
    x[i, ] = band( i-1, pot ) > 0;
  end;
  return( x );
finish;

a = FullFactorial( 4 );
print a [colname={A B C D}];
 
quit;

View solution in original post

27 REPLIES 27
PeterClemmensen
Tourmaline | Level 20

@DJ20 Welcome to the SAS Community 🙂

 

I moved your post to the SAS/IML forum.

PaigeMiller
Diamond | Level 26

I am trying to figure out the number of combinations of factors in factorial design

 

The number of combinations, as your code states, is 2**m. 

 

After this, I am confused, as you have solved the problem. Could you please explain further?

--
Paige Miller
DJ20
Obsidian | Level 7

I need to put them in a matrix form so I can use it in further calculations.

 

I need to combine my code so it depends on the number of factors. I.e if I have 3 factors it will calculate the number of combination swhich is 2**3 = 8 and output the matrix of 0's and 1's as well!!

Rick_SAS
SAS Super FREQ

You mention a matrix of zeros and ones, but your initial example used combinations of letters. What do you want the matrix to look like? For n=2, do you want the character matrix

"1"

"A"

"B"

"A B"

 

or do you want the numerical matrix 

{0 0,

 0 1,

 1 0,

1 1};

 

 

 

DJ20
Obsidian | Level 7

I want the numerical matrix as it is easier for me to use it later on with the rest of the calculations in my program.

 

btw the numerical matrix should be:

{0 0,

 1 0,

 0 1,

1 1};

 

IanWakeling
Barite | Level 11

If the order of the rows of the matrix is not important then the problem is equivalent to counting in binary.   For example

 

proc iml;

start FullFactorial( n );
  r = 2 ## n;
  x = j(r, n);
  pot = 2 ## ( (n-1):0 );
  do i = 1 to r;
    x[i, ] = band( i-1, pot ) > 0;
  end;
  return( x );
finish;

a = FullFactorial( 4 );
print a [colname={A B C D}];
 
quit;
DJ20
Obsidian | Level 7

I am really sorry I have been using SAS for a short period. Can you please explain the code a little bit.

 

Do you think it can be changed to appear in the opposite order ?

 

Thanks,

DJ

IanWakeling
Barite | Level 11

Like this?

 

proc iml;

start FullFactorial( n );
  r = 2 ## n;
  x = j(r, n);
  pot = 2 ## ( 0:(n-1) );  /* reversed powers of 2 in this line */
  do i = 1 to r;
    x[i, ] = band( i-1, pot ) > 0;
  end;
  return( x );
finish;

a = FullFactorial( 4 );
print a [colname={A B C D}];
 
quit;
DJ20
Obsidian | Level 7

Yes now its in the order I wanted. Sorry again I didn't understand the job of every step in this code because I am fairly new to SAS.

 

I appreciate your help,

DJ

Rick_SAS
SAS Super FREQ

Probably the simplest way is to use the EXPANDGRID function. You might need to sort the rows if the order is not in the order you want:

 

proc iml;
/* example for n=3 */
m = expandgrid(0:1, 0:1, 0:1);
print m;
/* if you want, you can sort: */
call sort(m, ncol(m):1); 
print m;

/* n=5 columns */
m = expandgrid(0:1, 0:1, 0:1, 0:1, 0:1);
call sort(m, ncol(m):1); 
print m;

 

DJ20
Obsidian | Level 7

Is it possible to put this within a do loop?

 

 

 

In my case I have different data sets with different number of factors and I need the program to work for all of them. 

The number of factors are calculated using a do loop, I want to put the "expandgrid" function within the loop so it prints the matrix of 0's and 1's depending on the number of factors. Is it possible?

PaigeMiller
Diamond | Level 26

@DJ20 wrote:

Is it possible to put this within a do loop?

 

 

 

In my case I have different data sets with different number of factors and I need the program to work for all of them. 

The number of factors are calculated using a do loop, I want to put the "expandgrid" function within the loop so it prints the matrix of 0's and 1's depending on the number of factors. Is it possible?


Yes, you can put any IML code into a DO loop. I am wondering if you really want a DO loop, or do you want to pass a parameter (the number of factors, let's say for example you have 5 in a particular data set) to some algorithm that then creates the matrix for 5 factors. You wouldn't want a DO loop that creates a matrix for 3 factors and then 4 factors and then 5 factors and so on ... you just want the matrix for 5 factors.

 

Please consider using PROC FACTEX to create the desired matrix. SAS has already done the work of programming it and debugging it and testing it, so you don't have to write your own code with DO loops and then debug it and test it.

--
Paige Miller
Rick_SAS
SAS Super FREQ

Yes, it is possible to generate the matrix for n factors. You can create a function that builds up the function call as a string and then uses CALL EXECUTE to generate the matrix:

 

proc iml;
start AllZeroOneComb(n);
   if n=1 then return ( {0,1} );
   cmd = "m = expandgrid(";
   do i = 1 to n-1;
      cmd = cmd + "0:1, ";
   end;
   cmd = cmd + "0:1);";
   *print cmd;
   CALL EXECUTE(cmd);
   return (m);
finish;

do n = 1 to 3;
   m = AllZeroOneComb(n);
   print m;
end;

You could also put Ian's algorithm into a function. Or any of the algorithms in the article, "Creating a matrix with all combinations of zeros and ones."

 

You can also pre-compute the matrices and stick them in a list. Then you don't need to recompute them for every data set.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 27 replies
  • 1172 views
  • 6 likes
  • 5 in conversation