![]() | ![]() | ![]() | ![]() |
|
SAS/IML is a powerful and flexible programming language capable of performing advanced mathematical and statistical computations. It is an integral component of the SAS intelligence architecture in that SAS/IML can read and write SAS data sets, just like the SAS DATA step.
One feature where SAS/IML could benefit in borrowing from the DATA step is its printing capability. The DATA step PUT statement is very advanced in options and has a multitude of features, while the SAS/IML PRINT statement is relatively simple in comparison. Ross Bettinger, a SAS Analytical Consultant, has written a macro
It produces the following output in the list file:
The Here is another example, involving row and column labeling:
It produces the following output in the list file:
Plainly,
Using the
where the available options are:
The %PRINTIML macro syntax is:
where the available printing-related RESET options are described in Table 1:
Table 1:
A Final Note
Appendix
Table A.1: Comparison Between SAS/IML RESET Statement and
Note: Only options related to printing are considered.
Table A.2: Comparison Between SAS/IML PRINT Statement and
About the author: Ross Bettinger is a SAS Analytical Consultant. He provides support for Enterprise Miner and has been involved with data mining projects for 7 years. He has been a SAS user for 15 years. His professional interests are related to data mining, statistical analysis of data, feature selection and transformation, model building, and algorithm development. |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
%macro PRINTIML( ARG )/ parmbuff ;
/* PURPOSE: enhance SAS/IML PRINT statement with additional capabilities
*
* NOTE: must use same SAS/IML syntax in %PRINTIML macro as in
* SAS/IML PRINT statement
*
* NOTE: must use backslash (\) after &ARG to indicate RESET settings
* to be applied to SAS/IML PRINT statement delimiter that
* delimiter that separates SAS/IML PRINT statement options from
* RESET options is backslash (\)
*
* NOTE: default values for RESET are: noautoname nocenter fw=9
* noname spaces=1
*
* NOTE: after printing, any specified RESET settings are restored to
* default values, regardless of former settings (simplistic
* approach due to inability to know value of RESET setting
* prior to invocation of %PRINTIML macro)
*
* SYNTAX: %PRINTIML( < matrices >
* < ( expression ) >
* < "message" >
* < pointer controls >
* < [options] >
* \ < RESET Options >
* )
*
* EXAMPLES OF USE:
* proc iml ;
*
* a = { 1 2 3, 4 5 6 } ;
* b = { 6 5 4, 3 2 1 } ;
*
* r_name = { 'row 1', 'row 2' } ;
*
* %PRINTIML( (( a + b )/ 7 ) \ center autoname spaces=3 fw=2 )
* %PRINTIML( ( a[ 1, ] ) ( b[ , 1 ] ) \ center autoname spaces=3 fw=2 )
* %PRINTIML( ( a + b )[ rowname=r_name format=10.5 ] \ spaces=1 )
* %PRINTIML( a , b / ( a + b ) \ spaces=1 )
* quit ;
*/
/* verify that PROC IML is licensed for use */
%if not %sysprod(IML)
%then %do ;
%put /-----------------------------------------------\ ;
%put | ERROR: PROC IML not licensed for your system. | ;
%put | Terminating macro %PRINTIML forthwith. | ;
%put \-----------------------------------------------/ ;
%goto L9999 ;
%end ;
/*#################################################################*/
/* begin macro execution
/*#################################################################*/
%let AUTONAME = noautoname ;
%let CENTER = nocenter ;
%let FW = ;
%let NAME = noname ;
%let SPACES = %str( spaces=1 ) ;
/*=================================================================*/
/* remove left, right parens from &SYSPBUFF
/* find start location of RESET options, if any (backslash
/* indicates that RESET options follow)
/*
/* note: spaces in %bquote fcn are included in result,
/* e.g., %bquote( A B C ) ne %bquote(A B C)
/*
/* note: must check for case when no RESET settings present
/*==================================================================*/
%let STRING = %qsubstr( %bquote(&SYSPBUFF), 2, %length(&SYSPBUFF) - 2 ) ;
%let STRING = %qleft(%qtrim(&STRING)) ;
%let STRING1 = %qsysfunc( reverse( &STRING )) ;
%let NDX = %index( &STRING1, %str(\)) ;
/*=================================================================*/
/* extract RESET settings from reversed string, reverse
/* again to create original order,
/* check for presence of settings. if none,
/* set &NDX = 0 to prevent further action
/*=================================================================*/
%if &NDX > 0
%then %do ;
%let SETTINGS = %qupcase( %qsubstr( %bquote(&STRING1), 1, &NDX - 1 )) ;
%let SETTINGS = %qsysfunc( reverse( &SETTINGS )) ;
/* if any complex expression closing character, e.g., ) ] }, found,
* no settings used.
* reset &NDX flag to prevent further parsing for settings
*/
%if %eval( %index( &SETTINGS, %str(%)))
+ %index( &SETTINGS, ] )
+ %index( &SETTINGS, } )) > 0
%then %let NDX = 0 ;
/* extract expression(s) to be printed from reversed string
* reverse again to restore original order
*/
%let STRING = %qsubstr( &STRING1, &NDX + 1 ) ;
%let STRING = %qsysfunc( reverse( &STRING )) ;
%end ;
/*==================================================================*/
/* insert blank around '[', '/', '(', ')', ',' to
/* distinguish potential options
/*==================================================================*/
%let BUFFER = ;
%do I = 1 %to %length( &STRING ) ;
%let STRING1 = %qsubstr( &STRING, &I, 1 ) ;
%if &STRING1 = [
or &STRING1 = %str(/)
or &STRING1 = %str(%()
or &STRING1 = %str(%))
or &STRING1 = %str(,)
%then %let BUFFER = &BUFFER%str( &STRING1 ) ;
%else %let BUFFER = &BUFFER.&STRING1 ;
%end ;
%let STRING = &BUFFER ;
/*==================================================================*/
/* create argument for SAS/IML PRINT statement
/* simple expressions , e.g., variable name,
/* not enclosed in parentheses
/* complex expressions, e.g., ( a + b / c * d[ +, 1] ),
/* must be enclosed in () pairs
/* options , e.g., [ format=10.5 ],
/* must be enclosed in [] pairs
/*==================================================================*/
%let NBKT = 0 ;
%let NPAR = 0 ;
%let NSTR = 0 ;
%let I = 1 ;
%let TOKEN1 = %qscan( %bquote(&STRING), &I, %str( )) ;
%do %until( &&TOKEN&I = ) ;
/*------------------------------------------------------------------*/
/* create macro vars to indicate presence/absence of (), []. set counters.
/*------------------------------------------------------------------*/
%let TOKEN_1 = %qsubstr( &&TOKEN&I, 1, 1 ) ;
%let TOKEN_2 = %qsubstr( &&TOKEN&I, %length( &&TOKEN&I ), 1 ) ;
/* process brackets */
%let LBKT&I = %eval( %index( &&TOKEN&I, [ ) > 0 ) ;
%let RBKT&I = %eval( %index( &&TOKEN&I, ] ) > 0 ) ;
%let NBKT = %eval( &NBKT + &&LBKT&I - &&RBKT&I ) ;
%let NBKT&I = %eval( &NBKT + &&RBKT&I ) ;
/* process parentheses */
%let LPAR&I = %eval( %index( &&TOKEN&I, %str(%() ) > 0 ) ;
%let RPAR&I = %eval( %index( &&TOKEN&I, %str(%)) ) > 0 ) ;
%let NPAR = %eval( &NPAR + &&LPAR&I - &&RPAR&I ) ;
%let NPAR&I = %eval( &NPAR + &&RPAR&I ) ;
%let EXPR_END&I = %eval( &&NPAR&I = 1 and &NPAR = 0 ) ;
/* process string quotes */
%let LSTR&I = %eval( &TOKEN_1 = %str(%') or &TOKEN_1 = %str(%")) ;
%let RSTR&I = %eval( &TOKEN_2 = %str(%') or &TOKEN_2 = %str(%")) ;
%let NSTR = %eval( &NSTR + &&LSTR&I - &&RSTR&I ) ;
%let NSTR&I = %eval( &NSTR + &&RSTR&I ) ;
%let I = %eval( &I + 1 ) ;
%let TOKEN&I = %qscan( &STRING, &I, %str( )) ;
%end ;
%let N_TOKEN = %eval( &I - 1 ) ;
/*==================================================================*/
/* assemble 3 cases:
/* simple expression # paren = 0
/* string expression # paren = 0, # strings > 0
/* complex expression # paren > 0, # strings > 0, # brackets > 0
/*==================================================================*/
%let BUFFER = ;
%let TOKEN = ;
%do I = 1 %to &N_TOKEN ;
%if &&NPAR&I = 0 and &&NSTR&I = 0 and
&&NBKT&I = 0 /* i.e., outside of (expression) */
%then %do ;
%if &&TOKEN&I ne %str(,) and &&TOKEN&I ne %str(/)
%then %let BUFFER = &BUFFER " &&TOKEN&I = " &&TOKEN&I ;
%else %let BUFFER = &BUFFER.%str( &&TOKEN&I )
;
%end ;
%else
%if &&NPAR&I = 0 and ( &&NSTR&I > 0 or &&NBKT&I > 0 )
/* 'message' or [options] but not (expression) */
%then %do ;
%let BUFFER = &BUFFER &&TOKEN&I ;
%end ;
%else %do ;
%let TOKEN = &TOKEN.&&TOKEN&I ; /* build (expression) */
%if &&EXPR_END&I /* have built (expression), put to output buffer */
%then %do ;
%let BUFFER = &BUFFER " &TOKEN. = " &TOKEN ;
%let TOKEN = ;
%end ;
%end ;
%end ;
/*=================================================================*/
/* if settings follow &ARG, parse them
/* from &SYSPBUFF and apply them
/*=================================================================*/
%if &NDX > 0
%then %do ;
%let I = 1 ;
%let TOKEN = %scan( &SETTINGS, 1, %str( )) ;
%do %while( %length( &TOKEN ) > 0 ) ;
%if &TOKEN = AUTONAME %then %let AUTONAME = autoname ;
%if &TOKEN = CENTER %then %let CENTER = center ;
%if %substr( &TOKEN, 1, 2 ) = FW %then %let FW = &TOKEN ;
%if &TOKEN = NAME %then %let NAME = name ;
%if %substr( &TOKEN, 1, 2 ) = SP %then %let SPACES = &TOKEN ;
%let I = %eval( &I + 1 ) ;
%let TOKEN = %scan( &SETTINGS, &I, %str( )) ;
%end ;
%end ;
reset &AUTONAME &CENTER &FW &NAME &SPACES ;
/* resolve SAS/IML PRINT statement */
print %unquote(&BUFFER) ;
/*=================================================================*/
/* invert settings, if any
/*=================================================================*/
%if &NDX > 0
%then %do ;
%if &AUTONAME ne %then %let AUTONAME = noautoname ;
%if &CENTER ne %then %let CENTER = nocenter ;
%if &FW ne %then %let FW = %str( FW=9 ) ;
%if &NAME ne %then %let NAME = noname ;
%if &SPACES ne %then %let SPACES = %str( SPACES=1 ) ;
reset &AUTONAME &CENTER &FW &NAME &SPACES ;
%end ;
%L9999:
%mend PRINTIML ;
These sample files and code examples are provided by SAS Institute Inc. "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Recipients acknowledge and agree that SAS Institute shall not be liable for any damages whatsoever arising out of their use of this material. In addition, SAS Institute will provide no support for the materials contained herein.
| Type: | Sample |
| Topic: | SAS Reference ==> Procedures ==> IML Analytics ==> Transformations Analytics ==> Time Series Analysis Analytics ==> Simulation Analytics ==> Regression Analytics ==> Matrix Programming Analytics ==> Mathematical Optimization Analytics ==> Forecasting Analytics ==> Financial Analysis SAS Reference ==> Macro Analytics ==> Exploratory Data Analysis Analytics ==> Descriptive Statistics |
| Date Modified: | 2005-06-01 11:39:52 |
| Date Created: | 2005-05-12 14:54:17 |
| Product Family | Product | Host | SAS Release | |
| Starting | Ending | |||
| SAS System | Base SAS | All | n/a | n/a |
| SAS System | SAS/IML | All | n/a | n/a |



