Date: Wed, 25 Jan 2006 16:21:03 +0000
Reply-To: iw1junk@COMCAST.NET
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ian Whitlock <iw1junk@COMCAST.NET>
Subject: Re: An array like string as macro parameter
Hari,
Your extra parentheses hide the commas from the macro facility. It worked
becasue IN will accept a list of lists. Others have turned to macro quoting to
hide the commas. Personally I would simply leave them out. IN does not
require a comma separated list. I would also leave out the quote marks and
turn that task over to a macro becasue I hate to type quote marks in long lists.
%macro qt ( list , qt = %str(%") , sep = %str(,)) ;
%*** return items quoted with &qt, and separated with &sep *** ;
%unquote(&qt%qsysfunc(tranwrd(%sysfunc(compbl(&list))
,%str( )
,&qt&sep &qt))&qt)
%mend qt ;
The subsetting statement would be
if &Var1 NOT in (%qt(&String));
Actually the macro by default puts in the commas because I copied the code
from a library of tools, but they are not required here.
In terms of technique you should ask whether a format would not be better.
%Macro SubsetMyway (data, out, Var1, fmt);
data &Out;
set &data;
where input(&Var1,&fmt..);
run;
%mend SubsetMyway ;
proc format ;
invalue sub
"id1" , "id2" ... = 1
other = 0 ;
run ;
%SubsetMyway (Big_Data, Small_data, ProductID, sub)
The format adds to the complexity but gives a binary search and may
package the list of IDs better. It is also far more applicable. With
a little work one might generate the WHERE statement
where input(&Var1,&fmt..) = 1 ;
or
where put(&Var1,&fmt..) = 1;
depending on whether &VAR1 is character or numeric. One way to cheat in
this determination might be to insist the format name begin with C or N.
I switched from IF to WHERE. Which is more efficient will depend on
whether than volume of data justifies the overhead cost in setting up the
more efficient WHERE processing. I changed the parameter names to DATA and
OUT in hopes that you might learn to use SAS-like parameter names. I did
not use keyword parameters because your call to the macro ended with semi-
colon.
Ian Whitlock
=================
Date: Tue, 24 Jan 2006 12:52:29 -0800
Reply-To: Hari <excel_hari@YAHOO.COM>
Sender: "SAS(r) Discussion"
From: Hari <excel_hari@YAHOO.COM>
Organization: http://groups.google.com
Subject: An array like string as macro parameter
Comments: To: sas-l
Content-Type: text/plain; charset="iso-8859-1"
Hi,
Though I have been able to do what I wanted to do, I still wanted your
guidance in understanding the same.
I want to go take a big set and make a smaller one in the following
way:-
%Macro SubsetMyway (InSASfile, OutSASfile, Var1, String);
data &OutSASfile;
set &InSASfile;
if &Var1 NOT in (&String);
run;
%mend SubsetMyway ;
%SubsetMyway (Big_Data, Small_data, ProductID, ("ID1", "ID2", "ID3"));
Now, the above call for the macro worked just fine. My reasoning for
putting brackets around the last parameter was that since there are
many ID's for a single parameter, so one would need a bracket and thus
it worked.
I wanted to see what happens by running without brackets and it gave me
an error something similar to "More number of positional parameters
than expected". Once I also tried to see by putting no brackets and a
single quote enclosing the whole parameter
%SubsetMyway (Big_Data, Small_data, ProductID, "ID1, ID2, ID3");
but obviously there was no change in small data set as compared to big
data set.
I want to know as to whether there are any other "legitimate" ways of
accomplishing the purpose of passing an array of values without using
brackets?
regards,
Hari
India