How to resolve macro variable in a loop in SAS

1k views Asked by At

I am trying to figure out how to call a macro variable in a loop within a data step in SAS, but I am lost; so I have 14 macro variables and I have to compare each of them to the entries of a vector. I tried:

data work.calendrier;
set projet.calendrier;
do i=1 to 3;
if date= "&vv&i"D then savinglight = 1;
end;
run; 

But it is not working. The variable vv1 up to vv3 are date variables. For instance this code works:

data work.calendrier;
set projet.calendrier;
*do i=1 to 3;
if date= "&vv1"D then savinglight = 1;
*end;
run; 

But with the loop it can not resolve the macro variable.

3

There are 3 answers

0
Andrew Haynes On

If you want to reference a macro variable with a number index like vv1,vv2,vv3 you need to resolve &i first.

SAS has a separate macro processor that resolves values before they reach the data step processor.

Essentially, you need to add extra ampersands at the beginning of your macro variable:

&&vv&i -> &vv1 -> "Value of vv1"
&&vv&i -> &vv2 -> "Value of vv2"
&&vv&i -> &vv3 -> "Value of vv3"

What happens here is that SAS reads in the information after the ampersand until it finds a break. SAS then resolves && as a single &, it then continues reading across until it resolves &i as a numeric value. You're then left with your required &vvi variable.

A couple of sources about this interesting topic:

http://www2.sas.com/proceedings/sugi29/063-29.pdf http://www.lexjansen.com/nesug/nesug04/pm/pm07.pdf

0
Tom On

Macro variable references are resolved before SAS compiles and runs your data step. You need to first figure out how to do what you want using SAS statements then, if necessary, you can use macro code to help you generate those statements.

If you want to test if a variable's value matches one of a list of values then consider using the IN operator.

data work.calendrier;
  set projet.calendrier;
  savinglight = date in ("&vv1"d,"&vv2"d,"&vv3"d);
run; 
0
DCR On

you need to use a macro. Here's the basic approach:

%let vv1 = 9;
%let vv2 = 2;
%let vv3 = 10;

data have;
drop i;
do i = 1 to 5;
date = i;
output;
end;
run;

%macro test;
data test;
set have;

%do i=1 %to 3;
 if date= &&vv&i then savinglight = 1;
%end;
run;
%mend test; 

%test;