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

Showing results for

- 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 10-25-2019 05:57 PM
(1445 views)

HI;

I would like to create a matrix reflecting a full factorial design. This would have the following structure

3 factors

0 0 1

0 1 0

1 0 0

0 1 1

1 1 0

1 0 1

1 1 1

I tried using allcomb but couldn't get a matrix like the above. Thanks

1 ACCEPTED SOLUTION

Accepted Solutions

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

If the factors all have 2 levels then the full factorial is nothing more than counting in binary. So you could use something like this:

```
x = j(8,3);
do i = 1 to 8;
x[i, ] = band(i-1, {4 2 1}) > 0;
end;
print x;
```

20 REPLIES 20

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

You can generate a full factorial matrix in PROC PLAN and then read it into IML if you need it there. SAS has done the work to generate all sorts of designs, so you don't have to. It's also simple to do via looping in a DATA step, and of course you could do similar looping in IML.

--

Paige Miller

Paige Miller

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

Thank you I am looking at both Proc Plan and Proc Factex, but they have some limits in terms of number of factors, It would be nice to be able to do this with loops and I have played around with the program below, but instead of outputting observations in the data step I would like to work solely in IML and generate a matrix. instead, Below is what I have so far. Thanks. I have more work to do!

data design;

do i=1 to 4;

do j=1 to 4;

output;

end;

end;

run;

proc print data=design;

run;

PROC IML;

USE design;

read all var _num_ into m [colname=varnames];

l=rowvec(m);

print (l);

run;

quit;

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

@Sanscrit_2prov wrote:

Thank you I am looking at both Proc Plan and Proc Factex, but they have some limits in terms of number of factors,

I am not aware of a limitation on the number of factors in PROC PLAN. There's nothing in the documentation stating a limit. Why do you say this?

but instead of outputting observations in the data step I would like to work solely in IML and generate a matrix.

Yes, looping in IML can give you a full factorial, but the idea of not using SAS data steps (or did you mean not using SAS data sets?) is one that will make your life miserable. SAS is designed around the concept of a data step, and around data sets, and unless you are determined to do everything in IML, you can't (and shouldn't) avoid using data sets and data steps.

--

Paige Miller

Paige Miller

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

Yes I should have clarified. I use a SAS dataset read into an IML matrix.

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

Thank you. Ian Wakeling solved my problem,

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

May I ask, why do you want to do this? Seems like its a part of a larger problem?

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

I am recoding a Matlab program into SAS code. So I am learning IML for the first time.

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

Use the function EXPANDGRID it does exactly what you want, provided you have 15 factors or less.

```
x = expandgrid(0:1, 0:1, 0:1);
print x;
```

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

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

If the factors all have 2 levels then the full factorial is nothing more than counting in binary. So you could use something like this:

```
x = j(8,3);
do i = 1 to 8;
x[i, ] = band(i-1, {4 2 1}) > 0;
end;
print x;
```

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

Thank you so much. This is exactly what I needed and was unaware of the band function.

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

If you do not need the individual elements but only the binary bit pattern, you can save quite a bit of memory by using a character string instead of a vector of 0/1 values. For example, compare BAND versus PUTN with a BINARYw. format:

```
proc iml;
n = 2##20;
x = band(n, 2##(20:0)) > 0;
print x;
y = putn(n, "binary20.");
print y;
```

For more examples and discussion, see "Creating a matrix with all combinations of zeros and ones."

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

I have a question.

Your code results in one row with 21 columns and the first column is a 1

How do I get all of the rows with the different columns equal to 1?

So let's say it was 4.

0000

0001

0010

etc

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

If you use the 'band' method, it only really makes sense to fill the matrix one row at a time as I have shown. I think Rick's point is mainly about storage space. As Paige has pointed out, the full-factorial matrix is going to be huge when you are looking at 2^16 or higher, and if you can manage with a character matrix, it will be reduce the memory requirement by a factor of 8. I have put both methods in to general modules below, so you can experiment.

```
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;
start FFstr( n );
fmt = cats("binary",char(n),".");
return( putn( t( 0:(2##n - 1) ), fmt) );
finish;
a = FullFactorial( 4 );
print a;
b = FFstr( 4 );
print b;
quit;
```

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.