1
votes

I have created a SAS macro, macro A, that takes in a variable name and returns transformed versions of that name i.e. if you run %A(asdf) you get out asdf_log asdf_exp asdf_10. I want to write another macro, macro B, that takes the output from the first macro and appends it together into a new macro variable.

%macro B(varList, outputName);
    %let &outputName = 
        %A(var1);
        %A(var2);
        ;
%mend

Is almost what I want to do, except that it obviously doesn't compile. I am also not sure if this is possible in SAS. As a further complication, the input to macro B is a list of variable that I want to run macro A for and append into one long list of variable names.

Why? Because I have a macro that runs on a list of variables and I want to run it on a transformed variable list.

Example: I have %let varList = x y; and I want as an output x_log x_exp x_10 y_log y_exp y_10. To do this I want two macros one, macro A, that returns the transformed variables names:

%macro A(var);
    &var._log
    &var._exp
    &var._10
%mend

I can't get the second macro (B as written above) to work properly.

2
Can you post some example values? At first blush it just looks like you have too many semi-colons.Tom
Hi Tom, yes, that won't run because of the weird placement of semi-colons. I'll give a more comprehensive example tomorrow. But, what I want is &outputName to contain the results from the running of macro A twice (or more times).Sheldon

2 Answers

2
votes

This is not too hard. You need to loop over the values in varList, appending results to outputName. You also need to declare outputName as GLOBAL so it will be accessible outside %B

%macro B(varList, outputName);
%global &outputName;
%let &outputName = ;

%local i n var;
%let n = %sysfunc(countw(&varList));

%do i=1 %to &n;
   %let var = %scan(&varList,&i);
   %let &outputName = &outputName %A(&var);
%end;
%mend;
2
votes

So if the inner macro is just returning characters, that is it doesn't actually generate any non macro statements, then why not make the outer one work the same way?

%macro inner(x);
  &x._log &x._exp &x._10
%mend;

%macro outer(list);
%local i;
%do i=1 %to %sysfunc(countw(&list));
 %inner(%scan(&list,&i))
%end;
%mend outer;

%let want=%outer(X y Z);