I would like to save all the vectors starting with letter 'a' to a matrix. We can assume that all such vectors are column vectors with the same length. The numbers of vectors whose name start with letter 'a' is variable, in the example below there are 2, but this number is not know at run time. There isn't any pattern in the vector names other than the fact that they start with 'a'
proc iml;
a_some_name = {1,2,3};
a_some_other_name = {4,5,6};
b = {1,1,1};
create mydata var {a_some_name a_some_other_name ...... a_random_name};
append;
close mydata;
quit;
If I could save the output from 'show names' to a matrix / vector, I could work with that.
Is there a way to do this?
Assuming that the names are a1, a2, ..., and the numerical suffixes are consecutive, you can use the index creation operator write the vectors to a data set:
k = 2; /* total number of vectors a1, a2, ..., ak */
varNames = "a1":("a"+strip(char(k)));
create mydata var varNames;
append;
close mydata;
Is there any pattern? Did you read them from a data set? If so, what is the naming convention?
Does this do what you want?
proc iml;
a_some_name = {1,2,3};
a_some_other_name = {4,5,6};
b = {1,1,1};
create mydata var _num_;
append;
close mydata;
quit;
data mydata;
set mydata(keep=a:);
run;
You might be left with blank rows if there are other larger matrices that are defined in IML.
It might still work, assuming most of the data that you don't want to write to disk is contained is a few matrices. Then you could delete these matrices before the CREATE using a FREE statement.
Interesting thing is you can use keyword _NUM_ to keep all the numeric vectors. then use another date step to keep all the variables which starts with A. proc iml; a1={1,2,3,4}; a2={4,5,6,7}; x={3,6}; create temp var _num_; append; close; quit; data want; set temp; keep a: ; run;
Ian has the right (write?) idea. First write ALL vectors to a data set. Then use a DATA step (inside the SUBMIT statement) to KEEP only those that begin with 'a'. Then read the names back into SAS/IML and write those vectors:
proc iml;
a1 = {1,2,3};
a2 = {4,5,6};
b = {1,1,1};
abigal = {0,2,1};
adam = {9,8,7};
k = 2; /* total number of vectors a1, a2, ..., ak */
varNames = "a1":("a"+strip(char(k)));
/* write all numerical vars */
create names var _NUM_; append; close;
/* keep only those that begin with 'a' */
submit;
data names(keep=a:);
set names(obs=1);
run;
endsubmit;
/* read the names of the variables that begin with 'a' */
use names;
read all var _NUM_ into JUNK[colname=varNames];
close names;
/* write the variables that begin with 'a' */
create mydata var varNames;
append;
close mydata;
I think the OP is worried that there is a large amount of other data in IML matrices that will be needlessly written out to a SAS data set. So a simple modification to Rick's code will avoid this. The 1st append statement can be removed, so only the headers are written to the names data set. Then the code in the submit block needs to be:
data names;
if 1=2 then set names(keep=a:);
output;
run;
This creates a singe record of missing values as there needs to be something to read back in to the JUNK matrix.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.