Date: Thu, 22 Apr 2004 12:38:57 -0400
Reply-To: "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Richard A. DeVenezia" <radevenz@IX.NETCOM.COM>
Subject: Re: Renaming - macro style help!
binger wrote:
> Hi all,
>
> I've got a dataset with a sequent number associated with it.
>
> If the sequence number is 1, then I want to keep all the variables
> named a1, b1, c1, d1,....up through a20, b20, c20, d20 named the same.
> If the sequence number is 2, then I want to rename all the variables
> to increase their value by 20, i.e. a1 becomes a21, b1 becomes
> b21,...and a20 becomes a40,b20 becomes b40, etc...
> This can carry on for many sequence numbers 3,4,5....
>
> I am having a terrible time getting this to work in a macro. I think
> its issues with using variable names in a macro, macro compiling,
> etc....
>
> I would post my code but Its been through too many iterations and
> sloppiness prevents me from seeing anything that is usable.
>
> Any thoughts, help...???
>
> Thanks!
Here is something a little more general.
* your app might always desire fromblock = toblock-1;
%macro nameBoost (data=, fromblock=1, toblock=2, blockstart=1,
blocksize=20);
%local oldLo oldHi newLo newHi;
%let oldLo = %sysevalf ( &blocksize * (&fromblock-1) + &blockstart );
%let oldHi = %sysevalf ( &blocksize * (&fromblock ) + &blockstart - 1 );
%let newLo = %sysevalf ( &blocksize * (&toblock-1) + &blockstart );
%let newHi = %sysevalf ( &blocksize * (&toblock ) + &blockstart - 1 );
%local ds nvars i varname L p n newn newname;
%let ds = %sysfunc(open (&data));
%let nvars = %sysfunc (attrn(&ds,nvars));
%do i = 1 %to &nvars;
%let varname = %sysfunc(varname(&ds,&i));
%let L = %length (&varname);
%* in reverse find position of first non-digit;
%let varname = %sysfunc(reverse(&varname));
%let p = %sysfunc (verify(&varname,0123456789));
%* convert to position of first of all digits after last non-digit;
%let varname = %sysfunc(reverse(&varname));
%let p = %eval(&L - &p+2);
%if &p <= &L %then %do;
%* check if numeric suffix in range for renaming;
%let n = %substr (&varname, &p);
%if &oldLo <= &n and &n <= &oldHi %then %do;
%let newn = %eval (&n - &oldLo + &newLo);
%let newname = %substr (&varname,1,%eval(&p-1))&newn;
%* emit text for use as interior of rename=(...) ;
&varname = &newname
%end;
%end;
%end;
%let ds = %sysfunc(close(&ds));
%mend;
data foo;
length a1-a20 8;
length b1-b20 $8;
length x y z aa bb cc 8;
retain _character_ '' _numeric_ .;
run;
options mprint;
data bar;
set foo (rename=(%nameBoost(data=foo, fromblock=1, toblock=2)));
run;
--
Richard A. DeVenezia
http://www.devenezia.com/downloads/sas/macros/