Is there a way that I can write SAS statistical graphics commands to an external file and then use the executefile() function to submit the code in the file for execution?
I know that IML has statistical graphics capability, but I want to write commands to the external file based on the parameters to a module and I need program-driven flexibility to do so.
For example, if there are two series, e.g., (x1, y1) and (x2,y2) then I want to tell SGPLOT to execute two SERIES statements. And if there are three series, I want to see three series on the plot that I generate.
Thus, I want my module to write the following external file for the following example:
<ODS html statements here>
proc sgplot data=sgplot_data ;
series x=x1 y=y1 ;
series x=x2 y=y2 ;
run ;
ODS html close ;
and for the second example:
<ODS html statements here>
proc sgplot data=sgplot_data ;
series x=x1 y=y1 ;
series x=x2 y=y2 ;
series x=x3 y=y3 ;
run ;
ODS html close ;
Executefile() will not do what you want as it is designed for including SAS/IML statements from a file. There are probably two options to do what you want - take a look at the submit/endsubmit statements which you can use to run general SAS statements from within an IML program. If this does not have the flexibility you need, then create a file from within IML that later is %included after IML has finished running. For example:
filename gcode "&mypath\graphics_code.sas";
proc iml;
file gcode;
nplot=3;
put 'proc sgplot data=sgplot_data;';
do i=1 to nplot;
s = 'series x=x' + strip(char(i)) + ' y=y' + strip(char(i)) + ';';
put s;
end;
put 'run;';
closefile gcode;
quit ;
%include gcode;
Well you could always 'submit' the include statement from within IML like this:
filename pcode "&mypath\procprint_code.sas";
proc iml;
file pcode;
put 'proc print data=sashelp.class;';
put 'run;';
closefile pcode;
submit;
%include pcode;
endsubmit;
quit ;
The cleanest solution is to write the data in long form, not wide form. Then the following SUBMIT/ENDSUBMIT call always use gives the correct number of lines with no special coding:
submit;
proc sgplot data=Have;
series x=x y=y / group=ID;
run;
endsubmit;
If the X variables are all the same, you can use the WIDETOLONG subroutine in PROC IML to create the long data. Otherwise, you can use something like the following:
data Have;
do x1 = 0 to 6 by 0.5;
x2 = -1 + 1.1*x1;
x3 = 1 + 0.9*x1;
y1 = sin(x1);
y2 = cos(x2);
y3 = exp(-x3);
output;
end;
run;
proc iml;
use Have;
read all var {x1 x2 x3} into XMat;
read all var {y1 y2 y3} into YMat;
close;
/* write data in long form. Remember: matrices are written in row-major order */
create Want var {x y ID};
x = T(XMat);
y = T(YMat);
ID = row(x);
append;
close;
submit;
proc sgplot data=Want;
series x=x y=y / group=ID;
run;
endsubmit;
You're not "exceeding the bounds of PROC IML." You can construct multiple statements and send them into the SUBMIT block, but it is easier and simpler to use use the GROUP= option.
BTW, you accidentally selected your own response as the correct answer.
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!
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.