0
votes

This code takes two macros and assigns them to arrays inside a data step, then loops through each variable defined in ln_vars, creating a new variable which is the natural log of the variable, appending _ln to the name

%let ln_vars = var1 var2;
%let ln_names = %add_string(&ln_vars, _ln);

data transform;
    set analysis;
    array ln &ln_vars;
    array ln_n &ln_names;
    *call execute ('%add_string(%str(&ln_vars), _ln)');

do over ln;
    ln_n = log(ln);
end;

run;

maybe there's a better idiom in sas code (I hope). I want to be able to just pass a single macro (the ln_vars macro) and call the %add_string() function from inside the data step. The commented 'call execute' returns the correct string, but when I try to

1588       array ln_n call execute ('%add_string(%str(&ln_vars), _ln)');
ERROR: Attempt to initialize variable call in numeric array ln_n with character constant
       '%add_string(%str(&ln_vars), _ln)'.
1
Before you try to automate, write code that executes successfully for one observation in analysis. Post that code (and sample data) and it will be easier to help.Jay Corbett
the code above works. I want to replace &ln_names in the data step with some version of the call execute command commented out below it.justin cress

1 Answers

2
votes

It would help if you gave us the definition of the %add_string macro. In any case, it looks like you need &ln_names to be a list of variables matching the list in &ln_vars except each variable has the suffix '_ln'.

If I'm correct, you don't really need the %add_string macro and could do this instead:

%let ln_vars = var1 var2;
%let ln_names = %sysfunc(tranwrd(&ln_vars,%str( ),%str(_ln )))_ln;
%put LN_VARS: &ln_vars;
%put LN_NAMES:&ln_names;

data transform;
  set analysis;
  array ln &ln_vars;
  array ln_n &ln_names;
  do over ln;
    ln_n = log(ln);
  end;
run;

Note that the two %put statements are not really necessary - they are just placed there to inspect the values of the two macro variables


As per your comment, you could have a macro:

%macro lnvars(vars=,suffix=_ln);

  %let newvars=%sysfunc(tranwrd(&vars,%str( ),%str(&suffix )))&suffix;

  array ln &vars.;
  array ln_n &newvars.;
  do over ln;
    ln_n = log(ln);
  end;

%mend;

and then call the macro from your data step as follows:

data transform;
  set analysis;
  %lnvars(vars=var1 var2);
run;

(Note, I've not tested the code, but you should get the general idea)