Reputation: 17
I'm new to SAS, I would like to produce plot for each random numerical vector. therefore I have wrapped my proc iml with a macro, and have tried to invoke it before calling the macro generate_scatter_plot. but I get the same set of points each iteration.
Can somebody please explain what is the proper way to do it SAS.
%MACRO generate_random_points();
proc iml;
N = 6;
rands = j(N,1);
call randgen(rands, 'Uniform'); /* SAS/IML 12.1 */
submit rands;
data my_data;
input x y @@;
datalines;
&rands
;
run;
endsubmit;
%MEND;
%MACRO generate_scatter_plot();
/* call execute('%generate_random_points();'); */
proc sgplot data=my_data;
scatter x=x y=y;
run;
%MEND;
data _null_;
do i = 1 to 20;
call execute('%generate_scatter_plot();');
end;
run;
I find SAS different from the rest of languages out there.
Thank you in advance to all who are willing to help!
Upvotes: 0
Views: 221
Reputation: 12909
Although you are using IML to pass data as text into a datalines
statement, you really do not need to do this. There are simpler ways of achieving your goal.
SAS does everything through datasets. They're analogous to Data Frames in Pandas. If you want to create a random vector of data, you'll create it within a dataset and use that within other procedures. datalines
should be avoided in production whenever possible. There are some very special cases where it is useful, but it's mainly used for sample data or prototyping.
SAS will randomly generate data based on the system clock unless you set a seed through call streaminit()
. You should always get new points. A much simpler way to achieve your results is shown below. The below macro will generate a new random dataset and plot it each time you call it.
%macro generate_scatter_plot(n=100);
data random;
do i = 1 to &n;
x = rand('uniform');
y = rand('uniform');
output;
end;
drop i;
run;
proc sgplot data=random;
scatter x=x y=y;
run;
%mend;
%generate_scatter_plot(n=100);
%generate_scatter_plot(n=1000);
Upvotes: 0
Reputation: 51591
If you are working in IML you should not have any need to use the SAS macro language to generate code.
You already showed how you can generate the random numbers into a IML matrix.
And you can use the SUBMIT/ENDSUBMIT block to call your PROC SGPLOT code.
What you seem to be missing is the IML syntax for converting a matrix into a dataset. https://blogs.sas.com/content/iml/2011/04/18/writing-data-from-a-matrix-to-a-sas-data-set.html
proc iml;
N = 6;
x = t(1:N);
y = j(N,1);
call randgen(y, 'Uniform');
create my_data var {x y};
append;
close my_data;
submit;
proc sgplot data=my_data;
scatter x=x y=y;
run;
endsubmit;
quit;
Upvotes: 0
Reputation: 21274
The following expands a bit on your logic to demonstrate the functionality of macro's.
options mprint mlogic;
%macro generate_random_points(Num=);
*Macro to generate random numbers;
*number of points generated are equal to the NUM=parameter;
data my_data;
do i=1 to &num.;
x=rand('uniform');
y=rand('uniform');
output;
end;
run;
%mend;
%macro generate_scatter_plot(Num_Points=);
*create random data with specified points;
%generate_random_points(Num=&Num_Points);
*graph data;
proc sgplot data=my_data;
scatter x=x y=y;
run;
%MEND;
*Run macro with different parameters in loop;
data _null_;
do i = 3 to 5;
call execute(catt('%generate_scatter_plot(Num_Points=', i, ');'));
end;
run;
option nomprint nomlogic;
And a slight variation on your process:
data _null_;
do i = 3 to 5;
call execute(catt("Title 'Num Points = ", i, " '; ", ' %generate_scatter_plot(Num_Points=', i, ');'));
end;
run;
Upvotes: 0