I've unsuccessfully attempted to use nested do loops to output the array observations to an empty dataset with variables x1-x&cols.
Any suggestions?
%let numrows=8;
%let numcols=3;
data work.test_combs_1;
input x1-x&numcols;
datalines;
. . .
;
run;
data work.test_combs_2;
set work.test_combs_1;
array test_array[&numrows,&numcols] (%eval(&numrows*&numcols)*0);
do i=1 to &numrows;
do j=1 to &numcols;
x&j = (test_array[i,j]);
output;
end;
end;
run;
num
You need to move the OUTPUT statement outside of the inner DO loop.
Move the values from the variables referenced by the multi-dimensional array to the variables referenced by the single dimension array and THEN write the values to the output dataset.
An ARRAY is a data step construct to allow you to reference one of a series of variables via an index.
How are you getting data into the ARRAY that you defined? Perhaps there is more to your program than you are showing?
So ignoring the issue of how you are going to get the data into your multi-dimensional array (AKA a matrix) here is how you could write that data out to a dataset.
So if you have 6 observations and 5 variables (AKA 6 rows and 5 columns) the code would look something like this:
data want;
array matrix [6,5] ;
array vars [5] age ht wt sysbp diabp;
* do something to populate the MATRIX array ;
* where is the data coming from? ;
* Write the matrix array to a dataset ;
do obs=1 to 6;
do col=1 to 5;
vars[col] = matrix[obs,col];
end;
output;
end;
run;
You need another array.
array test_array[&numrows,&numcols] (%eval(&numrows*&numcols)*0);
array x [&numcols] ;
do i=1 to &numrows;
do j=1 to &numcols;
x[j] = test_array[i,j];
Macro variables are not dataset variables. Also remember that the macro processor finishes modifying the code BEFORE the SAS compiler tries to interpret it. And so definitely BEFORE that data step can run. To see what code you are trying to run replace the macro variable references with example values.
But what are you trying to do? You are replicating every observation read from TEST_COMB_1 by a factoer of &num_rows times &num_cols. And you are setting all of the X variables to zeros because that is all you put into the array. Unless there are variables named TEST_ARRAY1,2,..... that you are reading from TEST_COMB_1. In which case why bother to set initial values when you define the array?
You need to move the OUTPUT statement outside of the inner DO loop.
Move the values from the variables referenced by the multi-dimensional array to the variables referenced by the single dimension array and THEN write the values to the output dataset.
An ARRAY is a data step construct to allow you to reference one of a series of variables via an index.
How are you getting data into the ARRAY that you defined? Perhaps there is more to your program than you are showing?
So ignoring the issue of how you are going to get the data into your multi-dimensional array (AKA a matrix) here is how you could write that data out to a dataset.
So if you have 6 observations and 5 variables (AKA 6 rows and 5 columns) the code would look something like this:
data want;
array matrix [6,5] ;
array vars [5] age ht wt sysbp diabp;
* do something to populate the MATRIX array ;
* where is the data coming from? ;
* Write the matrix array to a dataset ;
do obs=1 to 6;
do col=1 to 5;
vars[col] = matrix[obs,col];
end;
output;
end;
run;
@RobertWF1 wrote:
I've unsuccessfully attempted to use nested do loops to output the array observations to an empty dataset with variables x1-x&cols.
Why? The usage of arrays in sas differs in many ways from their usage in other programming languages: it is just a shortcut to access multiple variables defined in one observation, all having the same type. It seems as if you are trying to transpose a dataset, or am i on the wrong track?
A dataset is essentially a matrix with NOBS == NROWS and NVARS == NCOLS.
You can use a data step to multiply two such matrices (with a little work). I did that 25-30 years ago to deal with matrices my wife needed to multiply that were too large to load into memory to use IML (or PROC MATRIX back then).
You can also use PROC SCORE to multiply matrices.
@RobertWF1 wrote:
Ah, I just read the comments at the bottom of Rick Wicklin's post - and see that someone posted a simple macro for creating a dataset with all combinations of 1s and 0s, using a Cartesian product in proc sql. Very handy & simple to use, although not quite sure I understand what his code is doing here:
proc sql;
select memname into:d separated by ','
from dictionary.tables
where upcase(libname)="WORK" and upcase(substr(memname,1,3))="__D"
;
quit;
That step is making a macro variable, &D, that contains a space delimited list of all of the work datasets whose name starts with two underscores and the letter D. Presumably to be used later in a SET or other statement where you could reference a list of datasets.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.