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

I am trying to store unique matrices generated inside a PROC IML DO loop into corresponding unique SAS data sets.

 

I provide code below that is comprised by two parts.  Each part is followed by the corresponding comments ('*part 1;','*part 2;').

 

Part one generates a unique matrix with each iteration of the DO loop.  The matrix is called v and is dynamically labelled with each do loop.  So at the end of the two iterations, there will be two distinct matrices, one labelled "b1", the other "b2".

Part 1 works fine.  Part 2 is where I am having difficulty.

 

In Part 2, I want to store these two matrices labelled "b1" and "b2" into unique SAS data sets with distinct names.  That is, I would like to store matrix labelled "b1" into a SAS data set named work.b1 and matrix labelled "b2" into a SAS dataset named work.b2.

 

I've read Professor Wicklin's blogs which have gotten me close, but there appears to be an issue with my syntax in my CREATE and CLOSE statements in Part 2 of my code.

 

For those who might be interested, links to Professor Wicklin's blog posts that I reference follow:

 

https://blogs.sas.com/content/iml/2011/04/18/writing-data-from-a-matrix-to-a-sas-data-set.html

 

https://blogs.sas.com/content/iml/2013/07/29/read-data-sets-array-names.html

 

So here are my questions given what I've stated above:

 

1. How can I modify my Part 1 code so that I can have unique matrix names instead of unique matrix labels.  In other words, how can I have PROC IML create a matrix b1 and b2 instead of a matrix v  labelled "b1" and "b2" for iteration 1 and 2, respectively.

 

2. How can I modify my Part 2 code so that I can store the unique matrices created in Part 1 as unique SAS data sets.  Meaning, how can I store the matrix generated in each iteration into SAS data sets that each SAS data set has its own name -- so that they don't overwrite each other in the work library..

 

Hope some one can help me.

 

Thanks.

 

 

 

 

 

proc iml;

*part 1;

do a = 1 to 2;
names = "b" +strip(char(a,1));
b = j(3,3);
call randseed(1234);
call randgen(b,"Normal");
v = b;
call valset(names,v);
print v[l=names];

*part 2;

dsNames = {names};
create (dsNames[1]) from v;
append from v;
close (dsNames[1]);

end;

quit;

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

First, congratulations on being almost there. Your program just needs a small modification.

Here is the modification of your program:

proc iml;
b = j(3,3); 
call randseed(1234);
do a = 1 to 2; *part 1;
call randgen(b,"Normal"); *part 2; names = "b" +strip(char(a,1));
create (names) from b; append from b; close (names); end;

Notice that the (names) variable can be used directly on the CREATE statement. Also, there is no need to use VALSET to create a named matrix. You can reuse the matrix name (b) within each loop.

 

You didn't say what you are trying to accomplish, but often the next step is to analyze each of these data sets by using a SAS procedure (maybe PROC MEANS, CORR, or PRINCOMP.)  When you write multiple data sets with different names, it is hard to analyze them all. Most people will write a macro loop that iterates over the names of the data sets and calls a SAS procedure on each data set name.  This is inefficient, as shown in the article "Simulation in SAS: The slow way or the BY way."  

 

If you are heading in that direction, consider writing all samples into one data set and using an ID variable to indicate which observations correspond with each sample, as follows:

 

proc iml;
call randseed(1234);
varNames = "ID" || ("b1":"b3");
b = j(3,3);
ID = j(3,1,1);
M = ID || b; 
create Samples from M[colname=varNames];
*part 1;
do a = 1 to 2;
   call randgen(b,"Normal");
*part 2;
   M[,1] = a;   /* assign first column */
   M[,2:4] = b; /* assign columns 2,3,4 */
   append from M;
end;
close;
quit;

proc means data=Samples;
by ID;
run;

 

View solution in original post

2 REPLIES 2
Rick_SAS
SAS Super FREQ

First, congratulations on being almost there. Your program just needs a small modification.

Here is the modification of your program:

proc iml;
b = j(3,3); 
call randseed(1234);
do a = 1 to 2; *part 1;
call randgen(b,"Normal"); *part 2; names = "b" +strip(char(a,1));
create (names) from b; append from b; close (names); end;

Notice that the (names) variable can be used directly on the CREATE statement. Also, there is no need to use VALSET to create a named matrix. You can reuse the matrix name (b) within each loop.

 

You didn't say what you are trying to accomplish, but often the next step is to analyze each of these data sets by using a SAS procedure (maybe PROC MEANS, CORR, or PRINCOMP.)  When you write multiple data sets with different names, it is hard to analyze them all. Most people will write a macro loop that iterates over the names of the data sets and calls a SAS procedure on each data set name.  This is inefficient, as shown in the article "Simulation in SAS: The slow way or the BY way."  

 

If you are heading in that direction, consider writing all samples into one data set and using an ID variable to indicate which observations correspond with each sample, as follows:

 

proc iml;
call randseed(1234);
varNames = "ID" || ("b1":"b3");
b = j(3,3);
ID = j(3,1,1);
M = ID || b; 
create Samples from M[colname=varNames];
*part 1;
do a = 1 to 2;
   call randgen(b,"Normal");
*part 2;
   M[,1] = a;   /* assign first column */
   M[,2:4] = b; /* assign columns 2,3,4 */
   append from M;
end;
close;
quit;

proc means data=Samples;
by ID;
run;

 

Varrelle
Quartz | Level 8

Hi Professor Wicklin,

 

Thanks so much for answering my questions and anticipating my next steps!

 

Your response was very helpful and I am excited to apply your suggestions to the project I'm working on.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 2 replies
  • 1083 views
  • 1 like
  • 2 in conversation