Let's first outline our steps:
- get the list of variable names in the data
- add the postfix to each variable
- build the rename clause
- use sas procedure to rename
proc sql;
select name into :varnames separated by ' '
from sashelp.vcolumn
where libname="WORK" and memname="TEST";
This code generates the list in physical order. If you want to create a list in alphabetical order, you need to add "order by name" in the code.
We iterate variable names in the list and add the postfix to each name to create the new list. There are 3 parameters in this macro, list--the original list of names, pfix--the postfix and outlist--the name of the new list. If pfix is the empty, it adds variables order to the end.
%macro attach_char(list, pfix, outlist);
%let i=1;
%let item=%scan(&list, &i);
%let newlist=;
%do %while (&item ^= );
%if &pfix= %then %do;
%let newlist=&newlist &item.&i;
%end;
%else %do;
%let newlist=&newlist &item.&pfix;
%end;
%let i=%eval(&i+1);
%let item=%scan(&list, &i);
%end;
%let &outlist=&newlist;
%put &newlist;
%mend;
After generate the new list, we want to pair the new and old list. For example, the old list --V1, V2, V3, and the new list -- V1_o, V2_o, V3_o, we want to create a paired list:
V1=V1_o V2=V2_o V3=V3_o
%macro pair(lista, listb, operator, outlist);
%let i=1;
%let item1=%scan(&lista, &i);
%let item2=%scan(&listb, &i);
%let newlist=;
%do %while ((&item1 ^= ) and (&item2 ^= ));
%let newlist= &newlist &item1.&operator.&item2;
%let i=%eval(&i+1);
%let item1=%scan(&lista,&i);
%let item2=%scan(&listb,&i);
%end;
%put &newlist;
%let &outlist=&newlist;
%mend;
Now is the final step, rename the variables:
%let nlist=;
%let rnamelist=;
%attach_char(&varnames, _o ,nlist);
%pair(&varnames, &nlist, =, rnamelist);
proc datasets library=WORK nolist;
modify TEST;
rename
&rnamelist;
run;
We created two macros for the rename process. We do not have a single macro for this because every time we have different requirements. I prefer to keep small macros to increase the flexibility. For example, if you want to add "_o1", "_o2" etc to the end, we run twice of our attach_char macro to get the result, then run the pair macro. Using the same technique, you may also build macros for other request, adding prefix, replace a substring to another string etc.