330 likes | 515 Views
MASUG. May 19, 2005. I’d like to say…. Thank You! to SAS for sponsoring the food this evening. We have a new web URL!!! MASUGTN.org. SCSUG Training Day. June 9-11 in Little Rock, AR Presentations June 10 Workshops June 9 & 11 Presenters from SAS, SESUG, & MASUG
E N D
MASUG May 19, 2005
I’d like to say… Thank You! to SAS for sponsoring the food this evening.
We have a new web URL!!! MASUGTN.org
SCSUG Training Day • June 9-11 in Little Rock, AR • Presentations June 10 • Workshops June 9 & 11 • Presenters from SAS, SESUG, & MASUG • Postcards on registration table • Links posted on masugtn.org • or see SCSUG.com
SESUG Conference • October 23-25 in Portsmouth, VA • See link on our page • or go to SESUG.org
SUGI 31 • March 26-29 in San Francisco
Brief Announcement From Polly Mitchell-Guthrie Director, Americas Education Programs SAS
SAS Code • scatter3.sas and scatter4.sas will be posted on our web site after the meeting for your reference.
PLOT MATRICES Prepared by: Mehmet Kocak St. Jude Children’s Research
Scatter4 Macro • %macro scatter4(data, var1, var2, var3, var4, templib, templat, gname=gseg, ftitle=Scatter Plot Matrix);
Sample Data data sampledata; do i=1 to 100; iq=20+rand('normal')*2; age=iq+rand('normal'); weight=age+10+rand('normal')*5; height=weight+rand('exponential')*5; output; end; run;
Macro Program Execution %include "c:\mehmet_kocak\macros\scatter4.sas"; %scatter4(sampledata, iq, age, weight, height, mytemp.temps, scat4, gname=myfolder, ftitle=My Scatter Plot Matrix);
3x3 Scatter Plot Matrix • Scatter3.sas macro does the same thing for three variables of interest; • Template that produces a 10 panel plot (3x3+1 for title) is scat3. • If you like to use GSEG as your graphics output path, make sure that there is no graph in it before you run the macros. • Thanks….
SAS Code • scatter3.sas and scatter4.sas will be posted on the web site for reference.
More Tips & Tricks This is a macro that will receive a SAS Dataset name as a Parameter, and will build two GLOBAL variables (nbr_cols and nbr_obs). These are then available for use anywhere within that SAS session. It also writes out to the log a message helpful for debugging a SAS program.
%MACRO NUMOBS( DSN ); %GLOBAL nbr_cols nbr_obs; data _null_; set &dsn (obs=1) NOBS=obscnt; array aa {*} $ _character_; array nn {*} _numeric_; vars = dim(aa) + dim(nn); call symput('nbr_cols',vars); call symput('nbr_obs',obscnt); stop; run; (continued)
%let my_msg = %str(~~~ %TRIM( &Nbr_Obs) X %TRIM( Nnbr_Cols) Observations for &DSN ~~~); %let len = %LENGTH( &my_msg ); %let border=; %DO i = 1 %TO &LEN; %let border=&border~; %end; %put &border; %put &my_msg %NOW; %put &border; options &mprint &mlogic nonotes; run; %MEND NUMOBS; To use: %NUMOBS( my_sas_Dsn); It produces in the log: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ 44 X 11 Observations for my_sas_Dsn ~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macro Lists • A simple but powerful programming concept is a data list • A simple implementation of this in the SAS macro language is a single macro variable that contains the list • Each list element is delimited from another by a separator – usually a simple blank
What kind of things are useful as a macro list? • Variable names • Dataset names • Data from datasets • Dates • Control values • Devices, printers, files, etc
An example – variable names %let bylist = acode bcode ccode; %let metrix = x1 x2 x3 x4; proc sort data=myData; by &bylist t; proc summary nway; var &metrix; class &bylist t; output out=mySums sum=; proc print; var t &metrix; by &bylist; run;
Now comes the power part Frequently, multiple version of the same list would be very useful. %let metrix = x1 x2 x3 x4; %let totals = t_x1 t_x2 t_x3 t_x4; %let pcts = p_x1 p_x2 p_x3 p_x4; data stats; merge tbl1 tbl2; by &bylist t; array metrx &metrix; array totals &totals; array pcts &pcts; do over metrx; pcts = metrx / totals; end; run;
Where’s the power? Using macro lists makes code: • More readable • Easier to write • Easier to understand • Easier to maintain But wait, there’s more • Fewer “typo” errors – write the list once • Makes you more productive –faster coding and less debugging • Last (but especially important to the power issue) – lists can be manipulated!!
Prefixing elements in a list%LiPrefix • In the last example we typed each list (more opportunity for error) • Using a macro function, we type the list once, then simply build each derivative list: %let metrix = x1 x2 x3 x4; %let totals = %LiPrefix(&metrix,t_); %let pcts = %LiPrefix(&metrix,p_);
Adding a suffix%LiSuffix • Occasionally we want to use a suffix instead: %let metrix = adv yld wpp dpp; %do i=1 %to 9; %let varlist = %LiSuffix(&metrix,&i); data mydata&i; set mydata&i … keep &bylist &varlist; run; %end;
I’d like to rename a list of variables.How do I do that?! • Difficult with only LiPreffix and LiSuffix • Simple with RenameList: %let metrix = pkgs nrev brev disc wgt; %let totals = %LiPrefix(&metrix,t_); data myData; merge myData myTotals(rename=(%RenameList(&metrix,&totals))); by &bylist; run; RenameList builds the syntax especially for the rename clause
A Suite of Macro List Tools • LiPrefix, LiSuffix, RenameList • ListOp – list operations (union, intersection, subtraction) • Lindex – returns index number of a list element • Linsert – insert an element • ListContains – boolean, does the list contain the specified element? • QList – quotes each element of a list • CommaList – insert commas between elements of a list (for SQL lists) • WordCnt – returns number of elements • SubList – like substr but for lists • RevList – reverse the order of a list • PutList – formats each element using a SAS format • LastWord – returns the last element of a list • MakArray – transform a list into an array Email me to request a zip file: wjsmith1@fedex.com
LiPrefix /******************************************************************************* * Name: liprefix (List Item Prefix) * * Desc: Returns a list with the specified prefix prefixed to each item. * * Type: Macro Function - List * * Usage: %liprefix ( list , prefix ) * * Where: list is a space delimited list * * prefix is any string of characters * * Examples: * * 1) %let fylist=1996 1997 1998; * * %let newlist=%liprefix(&fylist,%str( FY)); * * %put ===> newlist=&newlist; * * ===> newlist=FY1996 FY1997 FY1998 * * 2) %let datelist=01JAN1999 01FEB1999 01MAR1999; * * %let newlist=%liprefix(&datelist,%bquote(')); * * %let newlist=%lisuffix(%bquote(&newlist),%bquote('d)); * * %put ===> newlist=&newlist; * * ===> newlist='01JAN1999'd '01FEB1999'd '01MAR1999'd * * History: * * 3/15/00 Walt Smith - development * *******************************************************************************/ %macro liprefix (_list,_pref) / des = 'Fn: Prefix each item in list with string' ; %local return i signal wrd delim; %let delim=%str( ); %let i=0; %let signal=CONTINUE; %do %until(&signal=DONE); %let i=%eval(&i +1); %let wrd=%qscan(&_list,&i,%str(&delim)); %if %length(&wrd)=0 %then %let signal=DONE; %else %let return = &return.%str(&_pref)%str(&wrd)%str(&delim); %end; %unquote(&return) %mend;
LiSuffix /******************************************************************************* * Name: lisuffix (List Item Suffix) * * Desc: Returns a list with the specified suffix appended to each item. * * Type: Macro Function - List * * Usage: %lisuffix ( list , suffix ) * * Where: list is a space delimited list * * suffix is any string of characters * * Examples: * * 1) %let fylist=1996 1997 1998; * * %let newlist=%lisuffix(&fylist,%str(,)); * * %put ===> newlist=&newlist; * * ===> newlist=1996,1997,1998, * * 2) %let datelist=01JAN1999 01FEB1999 01MAR1999; * * %let newlist=%liprefix(&datelist,%bquote(')); * * %let newlist=%lisuffix(%bquote(&newlist),%bquote('d)); * * %put ===> newlist=&newlist; * * ===> '01JAN1999'd '01FEB1999'd '01MAR1999'd * * History: * * 3/15/00 Walt Smith - development * *******************************************************************************/ %macro lisuffix (_list,_suff) / des = 'Fn: Suffix each item in list with string' ; %local return i signal wrd delim; %let delim=%str( ); %let i=0; %let signal=CONTINUE; %do %until(&signal=DONE); %let i=%eval(&i +1); %let wrd=%qscan(&_list,&i,%str(&delim)); %if %length(&wrd)=0 %then %let signal=DONE; %else %let return = &return.%str(&wrd)%str(&_suff)%str(&delim); %end; %unquote(&return) %mend;
Q & A with Chris Ricciardi Systems Engineer with SAS