Date: Wed, 20 Dec 2006 17:10:41 +0000
Reply-To: toby dunn <tobydunn@HOTMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: toby dunn <tobydunn@HOTMAIL.COM>
Subject: Re: another query on macro variable
In-Reply-To: <122020061701.21313.45896C670007501700005341220073407605029A06CE9907@comcast.net>
Content-Type: text/plain; format=flowed
Ian ,
I notice you switch th eway you count the number of elements in a list to:
%let num= %eval(%sysfunc(n(&list))+%sysfunc(nmiss(&list))) ;
Nice I like it shorter and sweeter than using CountC and %length.
Toby Dunn
To sensible men, every day is a day of reckoning. ~John W. Gardner
The important thing is this: To be able at any moment to sacrifice that
which we are for what we could become. ~Charles DuBois
Don't get your knickers in a knot. Nothing is solved and it just makes you
walk funny. ~Kathryn Carpenter
From: Ian Whitlock <iw1junk@COMCAST.NET>
Reply-To: iw1junk@COMCAST.NET
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: another query on macro variable
Date: Wed, 20 Dec 2006 17:01:27 +0000
Summary: More simplifying, more design issues
#iw-value=2
Zenny, Jim,
There is no need for the forward casting of variables here since they
can be easily calculated with %LET statements. In terms of design
macro appears to depend on one parameter - the list of numbers used
to initialize the array MEM. (Incidentally, I think this array might
better be _TEMPORARY_.) I called that parameter MEMS, thinking of
members of the array, but something more meaningful to the project
would be better.
There are SAS design problems to be overcome:
1) still no function to count words as far as I remember
2) %SYSFUNC doesn't work with OF modifier
Consequently a little preparation and complexity is required. Here
is the macro.
%macro aa (mems=4 1 8 3);
%LOCAL Num maxv list;
%let list = %sysfunc(compbl(&mems)) ;
%let list = %sysfunc(tranwrd(&list,%str( ),%str(,))) ;
%let num= %eval(%sysfunc(n(&list))+%sysfunc(nmiss(&list))) ;
%let maxv = %sysfunc(max(&list)) ;
data test2 ( drop = i j ) ;
array mem(&num) (&mems);
SET Test1;
ARRAY Credit (&num, &maxv) credit: ;
do i=1 to #
do j=1 to &maxv;
if j<=mem(i) then credit(I,J)=1;
end;
end;
run;
%mend;
data test1 ;
retain credit_1_1 credit_1_2 credit_1_3
credit_2_1 credit_2_2 credit_2_3
credit_3_1 credit_3_2 credit_3_3
2 ;
run ;
options mprint ;
%aa(mems=1 3 2)
I cheated in the creation of the CREDIT list of variables. Of course,
there should be a macro to make this list of names, but I will leave
that to a Coder's Corner paper I am writing for SGF (1?) on making
lists in general.
Ian Whitlock
=================
Date: Wed, 20 Dec 2006 03:23:22 -0500
Reply-To: Jim Groeneveld <jim2stat@YAHOO.CO.UK>
Sender: "SAS(r) Discussion"
From: Jim Groeneveld <jim2stat@YAHOO.CO.UK>
Subject: Re: another query on macro variable
Comments: To: pengz.q@GMAIL.COM
Hi Zenny,
A few (problematic) issues:
1. You can not refer to a macro variable (&maxv) in the same data step
where you created it using CALL SYMPUT. The fact that that does seem to
work may be that you rerun the data step within the same interactive SAS
session many times, so you have the macro variable from the previous run.
2. Furthermore, the creation of the SAS variables credit16, credit17,
credit34 and credit37 with missing values is due to the fact that there is
SAS code referring to them, though the condition to assign them another
value is never true. That implies SAS creates the variables with missing
values.
What do you want to do with this code? Let's simplify it:
%macro aa;
%LOCAL Num maxv;
%let num=3; * executes before the data step anyway;
data test1;
array mem(&num) (5 7 3);
maxv = mem(1);
Do i=1 to dim(mem)-1;
If mem(i)<mem(i+1) then maxv = mem(i+1);
End;
* Create macro variable maxv to assign dimension in next data step;
CALL SYMPUT ('maxv', COMPRESS(PUT(maxv,BEST12.)));
RUN;
DATA Test1;
SET Test1;
ARRAY Credit (&num, &maxv);
do i=1 to #
do j=1 to maxv; * maxv from Test1 or &maxv as macro var;
if j<=mem(i) then credit(I,J)=1;
end;
end;
run;
%mend;
%aa
Unassigned elements of array Credit have missing values.
This is untested code. But again: what do you want to reach with it?
What purpose does it serve? I think it may even be too complex.
Regards - Jim.
--
Jim Groeneveld, Netherlands
Statistician, SAS consultant
home.hccnet.nl/jim.groeneveld
My computer is a long way from home and only sparsely can access SAS-L.
On Tue, 19 Dec 2006 18:33:21 -0800, zenny <pengz.q@GMAIL.COM> wrote:
>Thanks everybody, my last query on macro variable is how to assign the
>dim of a array to a macro variable. many experts helped me out.
>Actually, it is not necessary to do that in my code. But when I failed
>to assign the dim of array to a macro variable, I wonder if I used the
>correct functions. So I rasied this issue. Sorry to bother everyone. My
>code needs to create new variables matching a matrix. For example, the
>history usage of the credit cards of each member in the household.
>Below code does this. However, I do not understand why it still creates
>variables credit16, 17 and credit34,37, with missing values.
>
>%macro aa;
>data test1;
>%let num=3;
>array mem(&num) (5 7 3);
>
>
>call symput('maxv',mem(1));
>Do i=1 to dim(mem)-1;
>If mem(i)<mem(i+1) then
>call symput('maxv',mem(i+1));
>End;
>
>
>%do i=1 %to #
> %do j=1 %to &maxv;
> if &j<=mem(&i) then credit&i&j=1;
> %end;
>%end;
>
>
>run;
>%mend;
>%aa
_________________________________________________________________
Dave vs. Carl: The Insignificant Championship Series. Who will win?
http://clk.atdmt.com/MSN/go/msnnkwsp0070000001msn/direct/01/?href=http://davevscarl.spaces.live.com/?icid=T001MSN38C07001