Help using Base SAS procedures

Dynamically setting start and end variable

Reply
Super Contributor
Posts: 259

Dynamically setting start and end variable


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

PROC Star
Posts: 7,363

Re: Dynamically setting start and end variable

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

Super User
Posts: 17,870

Re: Dynamically setting start and end variable

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;

Super User
Super User
Posts: 6,502

Re: Dynamically setting start and end variable

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 ;

Respected Advisor
Posts: 3,777

Re: Dynamically setting start and end variable

I thought macro variables could be 65534.  Guess I need to RTM.

Super User
Super User
Posts: 6,502

Re: Dynamically setting start and end variable

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

Super User
Super User
Posts: 6,502

Re: Dynamically setting start and end variable

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 ;

Ask a Question
Discussion stats
  • 6 replies
  • 255 views
  • 0 likes
  • 5 in conversation