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 ;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.