Turn on suggestions

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

Showing results for

Options

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

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 02-26-2020 09:06 AM
(659 views)

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

27 REPLIES 27

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

Paige Miller

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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?

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

@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

Paige Miller

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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.

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

**If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. **

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.