You want to run the macro %na_update for each value of var_name in the have data set, correct?
Ok. I'm not sure what you're aiming for here. The purpose of the macro is unclear to me.
However, speaking of the overall logic of you requirement, I would go about it differently. Instead of relying on the macro facility to generate the series of macro calls, I would use the Call Execute Routine and do something like this.
Obviously, this is untested, since I can't see your data.
/* Step 1 : Define the macro */
%macro na_update(var);
Data want;
set have;
&Var = tranwrd(&var, "NA", '0');
If &var="." then do &var = '0';
end;
run;
%mend;
/* Step 2 : Use Call Execute logic to call the macro for each value of var_name in have */
data _null_;
set have;
call execute('%nrstr(%na_update('||var_name||'))');
run;
%macro na_update(var);
data want;
set have;
&var = tranwrd(&var,'NA','0');
if &var="." then do &var='0';
end;
run;
%mend;
data _NULL_; set have;
call execute('%nrstr(%na_update('||var_name||'))');
run;
Tried this, log shows no error. But still its not giving the desired output.
@Deyanamika wrote:
%macro na_update(var);
data want;
set have;
&var = tranwrd(&var,'NA','0');
if &var="." then do &var='0';
end;
run;
%mend;
data _NULL_; set have;
call execute('%nrstr(%na_update('||var_name||'))');
run;
Tried this, log shows no error. But still its not giving the desired output.
It can't. In every iteration you create want from have, so only the result of the last iteration will persist (somebody else already told you this). Your macro code itself is therefore wrong and useless.
So you want to translate a bunch of variables, the names of which are saved in a macro variable.
This is done in a single data step, using data step tools (namely, an ARRAY), no macro needed.
data want;
set have;
array all_my_vars {*} &var_list.;
do i = 1 to dim(all_my_vars);
all_my_vars{i} = tranwrd(all_my_vars{i},"NA",'0');
if all_my_vars{i} = "." then all_my_vars{i} = '0';
end;
drop i;
run;
Given that you iterate over a quite long list of variables, you might consider if it makes sense to transpose your dataset to a long layout. This is especially true if your variable names contain information which is in fact data (like dates or group identifiers).
This worked. Thank you so much.
%na_update(& next_val);
The error is a typographical error, you have misspelled the macro variable name.
@Deyanamika wrote:
Yeah that's actually a typo here... I typed on phone actually.. sorry for bad indentation.
Please do not do this any more. It wastes your time, and it wastes our time. Please copy and paste the exact code you are using from now on.
The problem is that each time you call the macro you begin with the original data set HAVE, and write over the new data set WANT. None of the changes from the previous iteration are saved.
When you have 60 variables that you want to process in the same way, the usual method is to create an array (not a macro). Then have a single DATA step process every variable in the array.
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.