I would like to create a matrix reflecting a full factorial design. This would have the following structure
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
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.
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!
do i=1 to 4;
do j=1 to 4;
proc print data=design;
read all var _num_ into m [colname=varnames];
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.
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."
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;
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.