LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (September 2006, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Sat, 2 Sep 2006 18:25:40 -0400
Reply-To:   Arthur Tabachneck <art297@NETSCAPE.NET>
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   Arthur Tabachneck <art297@NETSCAPE.NET>
Subject:   Re: Macro vs user
Comments:   To: Ian Whitlock <iw1junk@COMCAST.NET>

Ian,

First, thanks for the link to Marriot reservations. The following is a link to my previous post which I think contains all three of the original posts: http://xrl.us/rjfv

I'm not going to defend the right of "users" to make use of SAS macros as, on this one occassion, I don't believe you've made a sufficient argument.

You also misrepresented Toby's example which was actually:

%Macro PrintIt( DataIn = ) ; Proc Print Data =&DataIn ; Run ; %Mend PrintIt ;

The fact that it required 34 extra keystrokes to code isn't the significant part but, rather, that it also requires the file name to be entered correctly every time it is run.

If, as a user I often print the file I've just worked on, it is much easier, quicker and less prone to errors for me to enter %print than it is to enter an alternative (other than an abbreviation for the above like the letter "P"). It also not prone to having the user enter an incorrect but valid filename and incorrectly think they are reviewing the correct data.

I don't at all question your comments regarding the uselessness of programs that don't correctly accomplish that for which they were intended, but I have seen many programs written by supposedly qualified "programmers" that don't meet that criterion.

Whenever I've had a "big" programming project, yes, I've contracted qualified SAS professional programmers. However, since they typically are not experts in the particular subject matter involved, I've found it most useful to provide them with a working, tested set of code that does what I need and asked them to restructure the code to ensure that it always provides valid results, in the shortest time, using the least possible resources and, hopefully, eliminating as much of the potential user error as possible.

However, that said, does one have to pass a particular test or attain a particular distinction before they will be "allowed" to use SAS macros? I don't believe that the SAS license contains any such requirement.

From a business perspective, of course, valid results without overusing the company's or organization's resources is critical. But that is up to the individual (user or programmer), company or organization to ensure, not SAS and definitely not SAS-L.

My point? If one can "use" or "program" SAS to correctly and defensibly accomplish what they need, within the time and resources they are alloted, then it is simply wrong to tell them that they are unqualified or that they can't take advantage of all of the SAS capabilities unless they make their code more complex to meet particular "programming principles" is simply not justified.

Art ---------- On Sat, 2 Sep 2006 20:04:52 +0000, Ian Whitlock <iw1junk@COMCAST.NET> wrote:

>Subject: Macro vs user >Originally: Re: OT: RE: Select column names based on the column values >Summary: The case against user written macros >Respondent: Ian Whitlock > >An interesting question arose from the original topic because Toby Dunn >emphasized a non-macro solution. For a message containing what is >sumarized here, see http://tinyurl.com/gxp5 > >Jack Clark asked, what was wrong with macros without parameters, >latter saying that he used them all the time because they let him >use macro instructions. > >Toby replied mentioning design flaws in macro design, probably >because he liked the sound of the words and has recently written a >NESUG paper on the subject. He then offered a macro having >little to do with anything except for the fact that it had no >parameters. > >TD> %Macro PrintIt ; >TD> Proc Print >TD> Data = XYZ ; >TD> Run ; >TD> %Mend PrintIt ; > >Arthur Tabachneck responded with a simplification claiming it to be more >useful saving (11) key strokes > >AT> %macro Print; >AT> Proc Print; >AT> Run ; >AT> %mend; > >and justified this work on the basis that **users** need to save time >and thus programming principles should not apply. That is the >question and one he has raised before in less stark terms. > >In this case, I think the saving in time is very questionable. How much >time is spent remembering to use the macro? How much time is spent when >without titles one get's confused at what data set is reported? How much >time is spent when applied to real sizable data sets? How much time is >spent when someone else has to run the program and it fails for lack of the >autocall library? Moreover, I suspect that all these prints may lead one >to think the work is adequately checked. Then how much time is lost when >the program contains a mistake? > >In a big project somebody thinking about saving a few key strokes is down >right dangerous. I already question the validity of any sizable project >developed by **users**, but to add that they should write and use macro >code makes the validity of the result so much more questionable. > >Now let's look at Jack's question in terms of the macro solution he >presented to the original question. "In this I want to select all the >column names having minimum value of -100. can I use sashelp.vcolumn." > >JC> data test; >JC> input col1 col2 col3; >JC> cards; >JC> 23 40 30 >JC> -100 30 40 >JC> 25 -100 35 >JC> ; >JC> run; >JC> >JC> proc sql noprint; >JC> select count(*),name >JC> into :vcnt, :vnames separated by ' ' >JC> from dictionary.columns >JC> where libname='WORK' and memname='TEST' >JC> ; >JC> quit; >JC> >JC> %put &vcnt; >JC> %put &vnames; >JC> >JC> >JC> %macro chkmin; >JC> >JC> %do i = 1 %to &vcnt; >JC> >JC> proc sql; >JC> %if &i = 1 %then %do; >JC> create table keepcols >JC> (col_name char(20)); >JC> %end; >JC> insert into keepcols >JC> select "%scan(&vnames,&i)" as col_name >JC> from test >JC> where %scan(&vnames,&i) <= -100 >JC> ; >JC> quit; >JC> >JC> %end; >JC> >JC> proc print data = keepcols; >JC> run; >JC> >JC> %mend chkmin; >JC> >JC> %chkmin; > >First of all, it tests for columns with values less than or equal to -100 >rather than for columns with a minimum of -100. Of course, this may have >been what was wanted or it may not matter. Then it sends the column name >to the table KEEPCOLS each time the condition is met. Consequently there >can be many unwanted duplicates. It is rather inefficient because it loads >SQL and does a separate SQL statement (data pass) for each column. Say >there are 100,000 observation and 100 columns, that is ten million >observations to process. Since Art has placed the emphasis for using macros >on time, this may be the most important reason for not using macros unless >developed by programmers worthy of the distinction between user and >programmer. > >There is no reason why, the SQL step before the macro, should not be inside >the macro. In a complex system it would be important to make the macro a >complete package without polluting the global name space. > >I think there are several reasons why it is questionable whether **users**, >as opposed to programmers, should be writing macros to save time: > > 1) Concentration on simple SAS helps produce reliability > 2) Concentration on macro means missing the opportunity for many better > solutions - stunting growth > 3) Concentration on macro writing without adequate testing techniques > reduces reliability > >The only saving grace is that users tend to write small simple programs >where the costs may not matter to anyone but the user, unless other people >depend on the results and their being efficiently obtained. I suspect that >users never recognize the costs in terms of time and reliability of writing >one use code in throw away macros. > >Ian Whitlock


Back to: Top of message | Previous page | Main SAS-L page