Showing posts with label Options. Show all posts
Showing posts with label Options. Show all posts

Tuesday, 1 November 2011

NOTE: Macro Options

Last week I wrote about the availability of the IN operator in macro through the use of the MINOPERATOR system option. I mentioned that SAS v9.0/9.1 had introduced a number of useful features to the SAS macro capability. Here are some options that you might find useful:

MPRINTNEST - Augments the information written to the log by MPRINT. If the MPRINT option has also been set, MPRINTNEST will show the level of nesting of macro calls, and the names of the nested macros. Very useful. V9.3 introduced a couple of new macro functions in this area: %SYSMEXECDEPTH returns the depth of nesting from the point of call, and %SYSMEXECNAME returns the name of the macro executing at a nesting level.

MCOMPILENOTE - Issues a message ot the log after a macro has been compiled. Successful completion of macro compilation is normally silent, so this forms a handy, positive confirmation.

MAUTOLOCDISPLAY - Echoes the source's location to the log each time an autocall macro is used (rather than once at compile-time). This provides a neat confirmation that SAS has picked-up the macro source from the directory you intended. In v9.3, MAUTOCOMPLOC specifies the location of an autocall macro when compiled by writing a message to the log.

Tuesday, 18 October 2011

NOTE: (Constructive) Feedback is Good

Sometimes it's adequate that SAS simply does what you ask. On other occasions, it's useful to know a little more detail of what SAS is doing on your behalf - maybe because it's making decisions for you, or maybe you're trying to figure-out a problem with your code.

Adding the FEEDBACK keyword to a PROC SQL statement will result in a bunch of useful information being written to the SAS log:
  • Any asterisk (for example, SELECT *) is expanded into the list of qualified columns that it represents. 
  • Any PROC SQL view is expanded into the underlying query. 
  • Macro variables are resolved. 
  • Parentheses are shown around all expressions to further indicate their order of evaluation. 
  • Comments are removed.
Here's an example log, showing the SELECT * being expanded and a macro variable being fully resolved (note how the column name is prefixed with the table name, and the sort order (ASC) is shown):


15 %let ob = age; 
16 proc sql feedback; 
17   select * 
18     from sashelp.class 
19     order by &ob 
20     ; 
NOTE: Statement transforms to: 


        select CLASS.Name, CLASS.Sex, CLASS.Age, CLASS.Height, CLASS.Weight 
          from SASHELP.CLASS 
      order by CLASS.Age asc; 


 21 quit; 

Quite apart from revealing some of what SAS is doing behind the scenes, the expansion of SELECT * into the log allows you to subsequently copy/paste the column names back into your program and then remove one or two that you don't want to keep.

Another good option for revealing information is OPTION MSGLEVEL=I. Setting this option will also result in some hitherto "secret" information being written to the SAS log. For example, SAS will tell you if it has used an index (and it will tell you which index it has used). Here's an example log (demonstrating how indexed data sets can be successfully read through a BY statement even if the data set is not physically sorted):

15 option msglevel=i; 
16 data holiday; 
17   set maps.spain2; 
18   by regname; 
19 run; 
INFO: Index REGNAME selected for BY clause processing. 
NOTE: There were 53 observations read from the data set MAPS.SPAIN2. 
NOTE: The data set WORK.HOLIDAY has 53 observations and 10 variables.

The FEEDBACK and MSGLEVEL options are both useful techniques to get more of an insight into what SAS is doing and hence what your program is doing.

Monday, 31 May 2010

NOTE: The APPEND & INSERT System Options

Did you spot the APPEND system option? And his compatriot INSERT? Both are extremely useful when you have a chain of configuration files. By default, the most recent specification of a system option (such as SASAUTOS) is the one that SAS will use. INSERT and APPEND allow you to add values to these options, either at the beginning (INSERT) or at the end (APPEND).

The full list of options to which INSERT and APPEND can be applied is: FMTSEARCH, HELPLOC, MAPS, MSG, SAMPLOC, SET, SASSCRIPT, SASAUTOS, or SASHELP.

So, for instance, if you have an installation-wide configuration file that specifies the standard SAS macro library concatenation, and you have an application-specific configuration file that needs to specify the application-specific macro library, you no longer need to repeat the standard SAS libraries in the app-specific config. Instead, you can just INSERT the app-specific library at the head of the concatenation and thereby de-couple your app-specific config file from the installation-wide config.

The SAS 9.2 Language Reference: Dictionary provides the low-down detail.

Monday, 5 October 2009

NOTE: More About NOTE2ERR (a.k.a. Be Of Good Type)

In an earlier post I wrote of the unsupported (and largely undocumented) NOTE2ERR system and data set option. It tells SAS to treat a certain number of "minor" syntax issues as errors instead of notes. Most notably this includes automatic conversion of characters values to numeric and vice-versa.


The post sparked conversation on SAS-L and amongst SAS practitioners at many of RTSL.eu's clients. The topic is clearly one that interests and is of use to many people. Sasplumber thought NOTE2ERR was awesome (and had some nice things to say about the blog too); Lou made a good point about protecting novice SAS programmers from their mistakes rather than punishing them; Ron Fehd suggested documentation could be found if one looked hard enough (fair point); and Jack Hamilton suggested an enhancement that would offer control over which note messages turned to errors (don't hold your breath on that one, Jack!).


The post ended with the comment "why hasn't NOTE2ERR been documented and supported?" Well, we got word from a SAS insider, and this is what they told us:
Interesting question, Andy! I never knew about NOTE2ERR, but I've dug into it and here is my take on it.
Sometimes, you want to hold your DATA step code to a higher standard. You want the DATA step to run quick and clean, and have complete confidence that it did just what you intended it to do. For example, the SAS Enterprise Miner product generates scoring code that often uses DATA step: very efficient, meant for high-use situations. NOTE2ERR allows a tester to ensure that the code being generated is not only error- and warning-free, but NOTE-free.
SAS emits a note because it wants you to be aware of something that you might not be aware of, even if most of the time it's not alarm-worthy. If you don't like those kinds of surprises, NOTE2ERR helps you ferret them out.
As to why it's not documented: it was added for internal use by SAS testers. Very occasionally a customer will call with a question where NOTE2ERR comes in handy, which is how (I suspect) the news of its existence got out.
Your blog post includes good caveats. PROC IMPORT is another one that can use DATA step. SAS proc developers are pretty disciplined about using ERRORs and WARNINGs appropriately. Does the same standard apply for NOTEs? I can't say, but NOTEs probably are not designed with the idea that an end user should be alarmed about them, so NOTE2ERR use as a constant practice might not be a great idea.
There's no specific comment about it becoming a supported feature, so we can assume it won't do so any time soon. But in the meantime, as our little birdy suggests, it's handy to use in testing and debugging.

Thursday, 17 September 2009

NOTE: Be Of Good Type (Revisited)

I love it when one discovery leads to another. In my previous blog entry I highlighted SAS V9.2's new NESTED argument for the DATA statement. Given that it's a new argument, I wouldn't expect it to work in previous versions of SAS, but it's always worth trying these things because often they were available in older versions of the software, albeit undocumented and unsupported. What did I discover when I tried NESTED in V9.1.3? It didn't work, but the error message told me of other DATA statement arguments I'd never come across before!

ERROR 22-322: Syntax error, expecting one of the following: BUFFERED, MISSOPT, NOMISSOPT, NONOTE2ERR, NOPASSTHRU, NOPMML, NOTE2ERR, PASSTHRU, PGM, PMML, UNBUFFERED, VIEW.

Whilst I recognised VIEW and a couple of others, I had to look-up the others in SAS documentation. I didn't find most of them, so I used Google. The most intriguing results were for (NO)NOTE2ERR.