I have a dataset with 70 or so vehicle factors. My sas program is setup so that it takes each factors and creates a number of different graphs for analysis. I have the code working perfectly for one factor and I want to expand it to include all factors using a macro. I would rather not have to individually call each factor as follows:
%macro1(factor1);
%macro1(factor2);
%macro1(factor3);
%macro1(factor4);
...
...
%macro1(factor70);
In the data set the factors are listed under field "Factor". Is there a way of scanning this field, working out how many factors there are and then using a dynamic approach to achieving what I am trying to above.
In my head, this would work like this:
scan column
there are x factors
do I from 1st to last factor
%macro(i)
end
Possibly something like:
%macro macro1(factor);
proc print data=sashelp.class;
where sex eq "&factor.";
run;
%mend;
%macro driver;
proc sql noprint;
select distinct factor
into :factors
separated by ' '
from sashelp.class (rename=(sex=factor))
;
quit;
%do i=1 %to &sqlobs;
%macro1(%scan(&factors.,&i.));
%end;
%mend;
%driver
Call execute works well for calling a macro multiple times:
data dates;
input date $;
datalines;
10nov97
11nov97
12nov97
;
data reptdata;
input date $ var1 var2;
datalines;
10nov97 25 10
10nov97 50 11
11nov97 23 10
11nov97 30 29
12nov97 33 44
12nov97 75 86
;
%macro rept(dat,a,dsn);
proc chart data=&dsn;
title "Chart for &dat";
where(date="&dat");
vbar &a;
run;
%mend rept;
data _null_;
set dates;
call execute('%rept('||date||','||'var1,reptdata)');
run;
When the number of values is reasonable then using SQL to build a macro variable is a useful way to do this, but note there is a limitation of 32,767 characters to a macro variable.
proc sql noprint ;
select distinct cats('%macro1(',factor,')')
into :mycode separated by ';'
from mytable
;
quit;
&mycode ;
I thought macro variables could be 65534. Guess I need to RTM.
I stand corrected.
2240 proc sql ;
2241 select x into :xx separated by ''
2242 from x
2243 where i<=1023
2244 ;
ERROR: The length of the value of the macro variable XX (65540) exceeds
the maximum length (65534). The value has been truncated to 65534
characters.
2245 %put %length(&xx);
65534
Writing lines of code to a file to be included later is another method for dynamic code generation.
filename mycode temp ;
data _null_;
set mytable ;
by factor ;
file mycode;
if first.factor then put '%macro1(' factor= ');' ;
run;
%include mycode / source2 ;
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 the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.