A SAS user told me that he computed a vector of values in the SAS/IML language and wanted to use those values on a statement in a SAS procedure. The particular application involved wanting to use the values on the ESTIMATE and CONTRAST statements in a SAS regression procedure, but my solution applies in general to any statement for any SAS procedure.

There are two ways to pass values from PROC IML to other procedures. One solution stores the values in a macro variable at run time. The other solution calls the SAS procedure from within the SAS/IML program and passes the SAS/IML vector as a parameter.

To give a concrete example, suppose that you have a set of numbers in a SAS/IML vector, and you want to use the numbers as a list of percentile values in PROC UNIVARIATE, as follows:

 /* Goal: specify a list of numbers to the PCTLPTS= option */ proc univariate data=sashelp.cars noprint; var MPG_City; output out=pctl pctlpre=p pctlpts=2.5 10 50 90 97.5; /* numbers go here */ run;

In this example, we assume that the numbers on the PCTLPTS= option are the result of some SAS/IML computation.

### The macro variable solution

The first solution converts the vector into a string of values that are separated by blanks. That string can then be placed in a macro variable. The macro variable can be referenced in the SAS procedure. The following steps create a macro variable from values in a SAS/IML row vector:

1. Convert the numeric vector into a character vector. You can use the PUTN function in Base SAS or the SAS/IML CHAR function to convert a numeric vector.
2. Use the ROWCAT function to concatenate the values into a single blank-delimited string of values. (If your values are in a column vector, transpose the vector before calling the ROWCAT function.)
3. Use the SYMPUT function to store the string of values in a macro variable.

You can then call PROC UNIVARIATE and reference the macro variable. The program follows:

 proc iml; pctl = {2.5 10 50 90 97.5}; /* these are the values */ s = rowcat( char(pctl)+" " ); /* separate by blanks and concatenate */ call symputx("PctList", s); /* create macro variable */ quit;   proc univariate data=sashelp.cars noprint; var MPG_City; output out=pctl pctlpre=p pctlpts=&PctList; /* use SAS/IML values here */ run;

I have used the same trick to pass values from SAS/IML vectors into Base SAS functions that expect a comma-delimited list. Use the macro variable solution when you are finished with PROC IML and are ready to use other procedures.

### An easier way: Use the SUBMIT statement

There is even an easier way that passes the values of a SAS/IML vector directly into a SAS procedure without creating a macro variable and without leaving PROC IML: use the SUBMIT and ENDSUBMIT statements.

 proc iml; pctl = {2.5 10 50 90 97.5};   submit pctl; proc univariate data=sashelp.cars noprint; var MPG_City; output out=pctl pctlpre=p pctlpts=&pctl; /* list from SAS/IML vector */ run; endsubmit;

If you include the name of a SAS/IML vector on the SUBMIT statement, the contents of that vector are substituted for the expression (in this case, &pctl) before the SUBMIT block is sent to SAS. Notice that there is not a macro variable called pctl. Although the &pctl expression looks like a macro variable substitution, it is actually accomplished through text substitution at run time, not through a macro preprocessor.

Use the SUBMIT method when you will need to compute further quantities in PROC IML. To learn more, watch my video about calling SAS functions from the SAS/IML language.

Share