If you want to do it with a macro, even though everybody seems to know better, here is a way:
%macro changenames;
data want;
set have;
%local i month months year;
%let months=jan feb mar apr may jun jul aug sep oct nov dec;
%do i=1 %to 36;
%let year=%eval(2010+(&i-1)/12);
%let month = %scan(&months, &i-12*((&i-1)/12));
rename VAR_&i. = var_&month._&year.;
%end;
run;
%mend changenames;
The macro really does not need a nested loop, you can calculate the year and month from the variable number. The catch is just understanding macro arithmetic, which is strictly integer, e.g. %eval(11/12) returns 0.
Of course you may want to rewrite the macro to use proc datasets to rename the variables in place instead of creating a new table.
Another possibility is to use SQL to create the content of the RENAME statement, which can be used in a datastep as well as proc datasets:
proc sql noprint;
create table vardates as select
name,intnx('month','31dec2009'd,input(scan(name,2,'_'),2.)) as date format=date9.
from dictionary.columns
where libname='WORK' and memname='HAVE' and name like 'VAR%';
select catx('_',name,'=VAR',put(date,year4.),put(date,monname3.)) into :rename separated by ' '
from vardates;
quit;
data want;
set have;
rename &rename;
run;
This is probably what I would do for such a task, it automatically adapts if you get more variables next month.
... View more