Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating a macro variable within a do loop

Status
Not open for further replies.

cstanyer

Programmer
Jan 20, 2009
1
GB
I'm stumped.

In the example below i have created the variables B1, B2, B3, B4 and B5. They have the values 1,5,2,6 and 3 respectively.

I have also created the variables M1, M2, M3, M4 and M5 using an array which I want to take the following values.

M1=B1;
M2=max(of B1-B2);
M3=max(of B1-B3) etc...

I need to do this within the do loop for various reasons which I won't go into now. Anyway, this code looks to me like it should work fine. But it doesn't. It looks like the Call Symput doesn't create the global variable &bobno until the datastep has finished running, I need the variable to be created during the do loop to ensure that the correct B1-B&bobno is created to give the correct value in M1-M5.

Help?

Sample Code:


data play;

array bob(5) B1-B5;

do i=1 to 5;
bob(i)=i*i;
end;

array maxi(5) M1-M5;

do i=1 to 5;
call symput ('bobno',compress('B'||i));
maxi(i)=max(of B1-&bobno);
end;

run;
 
That's correct, Call Symput generates macro variables which are only available OUTSIDE of the dataset.
Try using %let instead, that might work.

Chris
Business Analyst, Code Monkey, Data Wrangler.
SAS Guru.
 
Hi cstanyer,

The resolution of macro variables in the same step you created them isn't really the problem here. SAS determines what variables it will create in the PDV at compilation time. Whereas you are trying to treat the datastep as a typewriter and specify your variables at runtime. Don't worry, it is a reasonable assumption to make, I've been there too :).

You can return the value of a macro variable in the same datastep as the macro variable was created. Lets consider this example:

Code:
data _null_;
   call symputx('val1',999);
   val = symget('val1');
   put 'I am a dataset variable' val=;
   run;

%put I am a macro variable &val1;

log:

Code:
I am a dataset variableval=999
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

%put I am a macro variable &val1;
I am a macro variable 999

The caveat being that it has to be contained in a dataset variable, otherwise it would violate the SAS rule of defining all variables at compile time.

Anyway, for your particular problem, it would seem that serial ifs or a select/when statement would be an option. You could of course delegate this to the macro processor to generate the code for you. The macro code executes before the datastep code, therefore at compilation time for the datastep, the variables can be created:

Code:
data play;
  array bob(5) B1-B5;
  do i=1 to 5;
     bob(i)=ceil(ranuni(0))*100; *random test data;
     end;
  array maxi(5) M1-M5;
  M1=B1;
  %macro code;
  %do i=2 %to 5;
     M&i=max(of B1-B&i);
     %end;
  %mend code;
  %code;
  run;


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top