I'm trying to use the ExpandGrid function on several vertical vectors without knowing the number of vectors when the code is written, The example below shows a use case that creates 4 matrices (from A to D) each consisting of the cartesian product of two vectors. However, at run time there may be more (or fewer) matrices to create or vectors in each matrix. I know ExpandGrid requires between 2 and 15 vectors, so I'll make sure these limits are not exceeded.
How can this be written dynamically?
proc iml;
Var_1_A = {1, 4, 5, 7};
Var_1_B = {3, 4, 2};
Var_1_C = {10, 11};
Var_2_A = {11, 0, 2};
Var_2_B = {13, 2, 2, 5, 9};
Var_2_C = {10, 11};
/* Hard coded*/
CP_A = ExpangrGrid(Var_1_A, Var_2_A);
CP_B = ExpangrGrid(Var_1_B, Var_2_B);
CP_C = ExpangrGrid(Var_1_C, Var_2_C);
CP_D = ExpangrGrid(Var_1_D, Var_2_D);
quit;
One way is to use indirect assignment to iterate over the names of the variables that hold the data:
proc iml;
X1_1 = {1, 4, 5, 7};
X1_2 = {3, 4, 2};
X1_3 = {10, 11};
X2_1 = {11, 0, 2};
X2_2 = {13, 2, 2, 5, 9};
X2_3 = {10, 11};
/* create array of variable names for X and Y */
Vars1 = "x1_1":"x1_3";
Vars2 = "x2_1":"x2_3";
/* Loop over names of arrays. Use indirect assignment to
retreive information into temporary arrays X and Y
https://blogs.sas.com/content/iml/2011/03/23/indirect-assignment-how-to-create-and-use-matrices-named-x1-x2-xn.html
*/
do i = 1 to ncol(Vars1);
X = value( Vars1[i] );
Y = value( Vars2[i] );
G = expandgrid(X, Y);
/* do something with G */
msg = "Grid has " + char(nrow(G),2) + " pairs";
print i msg;
end;
Do you need all grids SIMULTANEOUSLY, or do you just need to loop over all combinations, generate the grid, do something with the grid, and then go on to the next combination?
One way is to use indirect assignment to iterate over the names of the variables that hold the data:
proc iml;
X1_1 = {1, 4, 5, 7};
X1_2 = {3, 4, 2};
X1_3 = {10, 11};
X2_1 = {11, 0, 2};
X2_2 = {13, 2, 2, 5, 9};
X2_3 = {10, 11};
/* create array of variable names for X and Y */
Vars1 = "x1_1":"x1_3";
Vars2 = "x2_1":"x2_3";
/* Loop over names of arrays. Use indirect assignment to
retreive information into temporary arrays X and Y
https://blogs.sas.com/content/iml/2011/03/23/indirect-assignment-how-to-create-and-use-matrices-named-x1-x2-xn.html
*/
do i = 1 to ncol(Vars1);
X = value( Vars1[i] );
Y = value( Vars2[i] );
G = expandgrid(X, Y);
/* do something with G */
msg = "Grid has " + char(nrow(G),2) + " pairs";
print i msg;
end;
If could make two datasets.
data x;
input id value1;
cards;
1 1
1 4
1 5
1 7
2 3
2 4
2 2
3 10
3 11
;
run;
data y;
input id value2;
cards;
1 11
1 0
1 2
2 13
2 2
2 2
2 5
2 9
3 10
3 11
;
run;
proc sql;
select x.*,value2
from x,y
where x.id=y.id;
quit;
if condition1 then
g = Expandgrid(X1_1, X1_2);
else
g = Expandgrid(X1_1, X1_2, X1_3);
Yes. I suggest CALL EXECUTE. You can build up the EXPANDGRID arguments dynamically:
proc iml;
x1 = 1:2;
x2 = 1:3;
x3 = -1:1;
condition = 0; /* set =1 for true */
str = "g = expandgrid(x1, x2";
if condition then
stmt = str + ", x3);";
else
stmt = str + ");";
call execute(stmt);
print g;
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.
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.