Date: Thu, 15 Jan 2004 15:46:32 -0500
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: Assign variables to a new variable based on variable names in
SAS
"W M" <mwx74@hotmail.com> wrote in message
news:cebd26c2.0401151102.5ab536d4@posting.google.com...
> Thank so much Nagakumar Sridhar and Fehd, Ronald J. for answering my
> previous
> question. However I was not clear in the original post. I modified my
> phrasing
> and the new version is below:
>
>
>
> I have met the following problem and I need your expert help.
> The variable names in the data set looks like this:
>
> a_1995q3 a_1995q4 a_1997q1 ........... a_2003q4 n
>
> Please note that "quarter" numbers in "a_****q*" variables may not be
> continuous, i.e. there might be a missing quarter.
>
> and n can have the value of any quarter for while a_quarter exists,
> say
> "1995q3", "20003q4".
>
> I need to do this:
>
> if n="1995q3" then new_a=a_1995q3;
> ..............
> if n="2003q4" then new_a=a_2003q4;
>
> I can use array to do this; but as time goes by, we will add variable
> a_2004q1
> to the list. Is there a way like
>
> new_a=a_{value of n} ?
>
> Because of the compilation of data step, you cannot do
>
> data new; set old;
> call symput("name", n);
> new_a=a_&n; (wrong !)
> run;
>
> Thanks so much, V.
V:
I can envision several a-postings involving SQL, DICTIONARY.COLUMNS and some
macro to generate if or select wallpaper code. I'll leave that to those who
will.
Here is an technique most wouldn't formulate. It is quite doable because
the 'indexing' component (while not as simple as 1..20 as in your first
post) still enjoys the happenstance of being eminently mappable to a
sequential integer. The mapping is the number of qtrs that n is from some
base qtr.
The following code generates some phony data and then performs the a_new =
a_{value-of-n} assignment without any wallpaper.
* pick random qtrs that will appear in the phony data;
data _null_;
qtr = intnx ('qtr', '01jan1995'd, 0);
do until (qtr > today());
if ranuni(1) > 0.35 then do;
nn+1;
call symput ('N' || put(nn,2.-L), put (qtr, yyq6.));
end;
qtr = intnx ('qtr', qtr, 1);
end;
call symput ('NN', put(NN,2.));
run;
* create the phony data;
%macro fauxData;
%local i j;
data faux (drop=j);
do row = 1 to 1000;
length n $6;
length a_new 8;
* assign values to the a_* columns;
%do i = 1 %to &NN;
a_&&N&i = int (ranuni(2)*1000);
%end;
* n corresponds to one of the a_{value-of-n} columns;
j = 1 + int(ranuni(0) * &NN);
n = symget ('N' || put(j,2.-L));
output;
end;
run;
%mend;
%fauxData;
* perform a_new = a_{value-of-n} assignment;
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;
--
Richard A. DeVenezia
http://www.devenezia.com/