Date: Mon, 14 Jun 2004 11:36:32 -0400
Reply-To: sashole@bellsouth.net
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Paul M. Dorfman" <sashole@BELLSOUTH.NET>
Organization: Sashole of Florida
Subject: Re: Macro [ab]usage (was: (OT) old style macro is still working)
In-Reply-To: <o%fzc.3$ag3.3253@news.uswest.net>
Content-Type: text/plain; charset="us-ascii"
Alan,
Methinks the gist of the thread (and my own opinion) is equilibrium. A few
points:
1) There are proper places for macros, put/include, call executes, the
interaction of SQL with the macro facility, etc.
2) Except for special cases, a macro overfills the cup when it gets to the
point of being used as data manipulation rather than code-assembling
language. 3) Even if prudence indicates that a macro has to be set aside in
favor of put/include and/or call execute, the macro still provides and
excellent shell for module encapsulation/parameterization.
4) Finally, when the logic in a multi-step program depends on events
occurring during macro execution, supplanting the macro logic with other
means, although undoubtedly possible, is likely to introduce more complexity
than simplification.
5) #4 should be no surprise, for in this case, macros are used squarely
their own domain, namely to conditionally assemble code based on events
resulting from steps already assembled and run - and not as a data
manipulation language, which further reinforces point #2.
Kind regards,
------------------
Paul M. Dorfman
Jacksonville, FL
------------------
> -----Original Message-----
> From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On
> Behalf Of Alan Churchill
> Sent: Monday, June 14, 2004 7:33 AM
> To: SAS-L@LISTSERV.UGA.EDU
> Subject: Re: Macro [ab]usage (was: (OT) old style macro is
> still working)
>
> I mostly abandoned the use of macros around 6 years ago and
> have encountered no major impediments.
> My experience is that the code is much easier to maintain and
> use. I supplanted with writes and includes and have never looked back.
>
> I realized how difficult macros were when I found myself
> looking at &&&var&&i and couldn't figure out my own code.
>
> IMO, macros compound code complexity and can make poor coding
> practices horrifiic.
>
> Alan
>
> "Huang, Ya" <yhuang@AMYLIN.COM> wrote in message
> news:200406130229.i5D2TrQ03664@listserv.cc.uga.edu...
> > On Sat, 12 Jun 2004 17:50:10 -0700, Roger DeAngelis
> <xlr82sas@AOL.COM>
> > wrote:
> >
> > >%soapbox on
> > >
> > > And you can do everthing that the SAS datastep language
> does in raw
> > >binary machine code.
> > >
> > >Consider the elegant code below by Dennis Diskin, many years ago.
> > >
> > >Can this code be improved by doing the whole process without one
> > >macro variable?
> > >
> > >The macro language is a natural way to communicate between
> the many
> > >languages in SAS ( Command Line/SAS
> Procedures/Datasteps/IML/SCL/..)
> > >
> > >I would very much like to see a more elegant solution
> without macro
> > >variables. (Go to it please!!!)
> > >
> > >
> > >/*----------------------------------------------------*\
> > >| Creates 27 Tables One for each Country |
> > >| From aggregate Countries Table |
> > >| Spain |
> > >| Germany |
> > >| France |
> > >| Britain |
> > >| USA |
> > >| Mexico |
> > >| .... |
> > >\*----------------------------------------------------*/
> > >
> > >
> > >%macro split(dsn=Countries)/Des="Create a table for each Country"
> > >
> > > /*----------------------------------------------------*\
> > > | Create macro array ( each element is country name) |
> > > | Country1 = Spain, Country2=France etc |
> > > | This macro can be used to split any aggregate data |
> > > | based on the values in a character column |
> > > \*----------------------------------------------------*/
> > >
> > > proc sql noprint;
> > > select distinct trim(Country) into :Country1 thru :Country999
> > > from
> > &dsn;
> > > %let nCountrys = &sqlobs;
> > > quit;
> > > run;
> > >
> > > /*----------------------------------------------------*\
> > > | Data Spain France Germany.. |
> > > | If Country = 'Spain' then output Spain |
> > > \*----------------------------------------------------*/
> > >
> > > data
> > > %do i = 1 %to &nCountrys;
> > > &&Country&i
> > > %end;
> > > ;
> > > set &dsn;
> > > select;
> > > %do i = 1 %to &nCountrys;
> > > when (Country= "&&Country&i") output &&Country&i;
> > > %end;
> > > otherwise;
> > > end;
> > > run;
> > >
> > >%mend split;
> > >
> > >%Split;
> > >
> > >%soapbox off
> > >
> > >
> >
> > I try to not to use macro if possible:
> >
> > data xx;
> > input country $ whatever;
> > cards;
> > Spain 1
> > Spain 4
> > Spain 12
> > Germany 3
> > Germany 5
> > Germany 7
> > Germany 9
> > France 9
> > Britain 100
> > USA 11
> > Mexico 90
> > ;
> >
> > proc sort;
> > by country;
> > run;
> >
> > data _null_;
> > set xx;
> > by country;
> > if first.country then do;
> > call execute('data '||country||'; set xx; if
> country="'||country||'";
> > run;'); end; run;
> >
> > Maybe somewhat slow, but code is simple and easy to read.
> >
> > Kind regards,
> >
> > Ya Huang
>
|