Chang,
I agree with your assessment of Richard's code. I especially liked that he offered it without any chest pounding!
Joe
-----Original Message-----
From: "Chang Y. Chung" <chang_y_chung@HOTMAIL.COM>
Sent: Jan 16, 2004 11:19 AM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: Assign variables to a new variable based on variable names in SAS
Hi, Richard,
Your data step, "monkeyshines" is one of the prettest I have ever seen.
Really nice.
The to-the-point array statement using the variable name wild character
(":"); use of lbound() hbound() functions; use of _i_ for index variable;
short but intuitive variable and array names like aVars, aBase, and aMap;
use of intnx and intck functions, reading the returned variable name
with ??yyq6. format, anticipation of range checking, and all the work was
done in essentially a single line!("a_new = aVars[aMap[qtrIndex]];") ... I
learn a lot just by reading your code!
All I could come up(at the bottom) was, in comparison, uh... ugly... slow,
and lacked much of the error checking and handling. Even though it is not
a wallpaper code... :-)
Cheers,
Chang
>data monkeyshines;
> set faux;
> array aVars a_: ;
>
> length varname $32;
>
> retain aBase;
> array aMap [1000] _temporary_;
>
> if _n_ = 1 then do;
> * determine intermediate mapping array;
> * tells us which qtr belongs to which a_* variable;
> aBase = intnx ('qtr', '01jan1960'd, 0);
> do _i_ = lbound(aVars) to hbound(aVars);
> call vname (aVars(_i_), varname);
> qtr = input (substr(varname,3),??yyq6.);
> if qtr ne . then do;
> qtrIndex = intck ('qtr', aBase, qtr);
> * range checking could go here;
> aMap [qtrIndex] = _i_;
> end;
> end;
> end;
>
> qtr = input (n,??yyq6.);
> if qtr then do;
> qtrIndex = intck ('qtr', aBase, qtr);
> * range checking could go here;
> a_new = aVars[aMap[qtrIndex]];
> end;
>run;
<sasl:code>
proc print data=faux(obs=3);
var row n a_new a_1996q3 a_1999q2 a_2003q1;
run;
/* on lst
Obs row n a_new a_1996Q3 a_1999Q2 a_2003Q1
1 1 1996Q3 . 843 638 574
2 2 1999Q2 . 862 359 330
3 3 2003Q1 . 44 893 540
*/
/* slow but works. not a wallpaper code, either.
by chang y chung 2004-01-16 */
%macro new_a(obs);
%local dsid rc;
%let dsid = %sysfunc(open(work.faux));
%let rc = %sysfunc(fetchobs(&dsid., &obs.));
%*;%sysfunc(getvarn(&dsid.,%sysfunc(varnum(&dsid.,a_&n.))))
%let rc =%sysfunc(close(&dsid.));
%mend;
data two;
set faux(obs=3);
call symput('n', n);
new_a = input(resolve('%new_a(' || put(_n_,best.) || ')'),best.);
put n= new_a=;
run;
/* on log
n=1996Q3 new_a=843
n=1999Q2 new_a=359
n=2003Q1 new_a=540
*/
</sasl:code>
|