Showing posts with label Macro. Show all posts
Showing posts with label Macro. Show all posts

Monday, March 5, 2012

Use GREPLAY to create multiple graphs per page

Desired result:


This sample program uses PROC GREPLAY together with macro code to dynamically replay a specific number of graphs per page.

The graphics output in the Results tab was produced using SAS® 9.2. Submitting the sample code with releases of SAS prior to SAS 9.2 might produce different results.

/* Delete any old entries in WORK.GSEG catalog */
proc greplay nofs igout=work.gseg;
delete _all_;
run;
quit;

/* Specify macro debugging options */
options mprint mlogic symbolgen;

goptions reset=all device=gif;

/* Macro MAKEGRAF creates GSLIDE graph entries that are TREPLAYED */
/* by PROC GREPLAY later in this program. Remove the %DO loop and GSLIDE */
/* procedure and place your code within the MAKEGRAF macro when you are */
/* ready to create your own individual graph entries. */
%macro makegraf;
%do i=1 %to 6;
proc gslide;
title1 "GRAPH &i";
run;
quit;
%end;
%mend makegraf;

/* This macro will dynamically treplay a specified number of grseg entries */
/* per page/screen. The specified values for the parameters */
/* ACROSS and DOWN will determine the number of panels in the template */
/* and the number of graphs per page/screen. */
%MACRO PERPAGE(across,down);

/* Create macro variable perpage */
%let perpage=%eval(&across*&down);

/* Use DSGI functions HSIZE/VSIZE to determine default HSIZE and VSIZE */
/* and modify for correct aspect ratio. */
data garea;
rc=ginit();
call gask('hsize',hsize,rc);
hsze=hsize/&across;
call symput('hsize',left(trim(hsze)));
call gask('vsize',vsize,rc);
vsze=vsize/&down;
call symput('vsize',left(trim(vsze)));
rc=gterm();
run;

/* Adjust VSIZE and HSIZE to reflect dimension of template panel. */
/* Turn DISPLAY off. */
goptions nodisplay vsize=&vsize hsize=&hsize;

/* Invoke macro MAKEGRAF, */
/* gslide entries created in WORK.GSEG catalog. */
%makegraf

/* Use DSGI function NUMGRAPH to determine the number of entries in */
/* WORK.GSEG catalog. */
data numgraf;
rc=gset('catalog','work','gseg');
rc=ginit();
call gask('numgraph',grsegcnt,rc);
call symput('grsegcnt',grsegcnt);
call symput('loopit',ceil(grsegcnt/&perpage));
ymult=100/&down;
xmult=100/&across;
rc=gterm();
run;

/* Calculate the panel coordinates for template */
data coord;
set numgraf;
do x=0 to (100-xmult) by xmult;
llx=x;
ulx=x;
urx=x+xmult;
lrx=x+xmult;
do y=0 to (100-ymult) by ymult;
lly=y;
uly=y+ymult;
ury=y+ymult;
lry=y;
output;
end;
end;
run;

proc sort;
by descending y;
run;

/* Create macro variables that resolve to panel coordinates */
data mccoord;
set coord end=eof;
call symput('llx'||left(_n_),llx);
call symput('ulx'||left(_n_),ulx);
call symput('urx'||left(_n_),urx);
call symput('lrx'||left(_n_),lrx);

call symput('lly'||left(_n_),lly);
call symput('uly'||left(_n_),uly);
call symput('ury'||left(_n_),ury);
call symput('lry'||left(_n_),lry);

if eof then call symput('total',_n_);
run;

/* Macro to create template */
%macro tempdef;
%do i=1 %to &total;
&i / llx=&&llx&i lly=&&lly&i
ulx=&&ulx&i uly=&&uly&i
urx=&&urx&i ury=&&ury&i
lrx=&&lrx&i lry=&&lry&i
color=black
%end;
%mend tempdef;

/* Macro to generate TREPLAY statement for GREPLAY */
%macro tplay;
%do j=1 %to &perpage;
%if %eval(&i*&perpage-(&perpage-&j)) <= &grsegcnt %then
&j:%eval(&i*&perpage-(&perpage-&j));
%end;
%mend tplay;

/* Macro to generate templated grseg entries */
%macro greplay;
proc greplay nofs igout=work.gseg tc=tempcat;
tdef spec&perpage
%tempdef;
template spec&perpage;
%do i=1 %to &loopit;
treplay %tplay;
run;
%end;
quit;

%mend greplay;

/* Reset the graphics options */
goptions reset=all device=gif
gsfname=grafout gsfmode=replace
xpixels=600 ypixels=400;

filename grafout 'c:\temp\test.gif';

/* Invoke the GREPLAY macro */
%greplay

%MEND PERPAGE;

/* Invoke the PERPAGE macro, specifying how you */
/* want the graphs laid out on the page. */
%PERPAGE(across=2,down=3);

Copied from SAS KNOWLEDGE BASE / SAMPLES & SAS NOTES

Tuesday, November 30, 2010

Use DO WHILE to read in every word in a string

%local cnt tword ntot1;

%let cnt=1;
%let tword=%qscan(&tstring,&cnt,%str( ));
%* let ntot1=%qscan(&tcount,&cnt,%str( ));

%do %while(&tword ne);

      data _null_;
            set &dir..&dsn;
            if &tname="&tword";
            call symput('twlbl',trim(left(&tlname)));
      run;

      %concat; *** Macro program is appended after Macro descrip;

      %let cnt=%eval(&cnt+1);
      %let tword=%qscan(&tstring,&cnt,%str( ));
      %* let ntot1=%qscan(&tcount,&cnt,%str( ));

%end; *** End of While(tword ne);

%let cnt=%eval(&cnt-1);

Thursday, November 18, 2010

Rename all vars in a dataset using SASHELP

*Create a temporary dataset... DSN;
data dsn;
a=1;
b=2;
c=3;
d=4;
e=5;
f=6;
run;


%macro test(lib,dsn);

*/1)*/ data _null_;
      set sashelp.vtable(where=(libname="&LIB" and memname="&DSN"));
      call symput('nvars',nvar);
run;

*/2)*/ data dsn;
      set sashelp.vcolumn(where=(libname="&LIB" and memname="&DSN"));
      call symput(cats("var",_n_),name);
run;

*/3)*/ proc datasets library=&LIB;
      modify &DSN;
      rename
      %do i = 1 %to &nvars;
            &&var&i=Rename_&&var&i.
      %end;
      ;
quit;
run;
%mend;

%test(WORK,DSN);

Wednesday, June 16, 2010

Handling leading, trailing blanks in macro variable

If a macro variable contains leading or trailing blanks, they can be easily removed without the use of %LEFT or %TRIM. Simply:

%let macvar = &macvar;

Wednesday, April 14, 2010

Read all files in one directory

%macro readraw(dir=.);

%local fileref rc did dnum dmem memname;
%let fileref=thisdir;
%let rc=%sysfunc(filename(fileref,&dir));
%let did=%sysfunc(dopen(&fileref));
%let dnum=%sysfunc(dnum(&did));

%do dmem=1 %to &dnum;
%let memname=%sysfunc(dread(&did, &dmem));
%if %upcase(%scan(&memname,-1,.)) = DAT %then %do;
%let dataset=%scan(&memname,1,.);
data &dataset;
infile "&dir\&memname";
input Course_code $4. Location $15. Begin_date date9.;
format Begin_date date9.;
run;

proc print data=&dataset;
title "%trim(&syslast)";
run;
%end;
%end;
%let rc=%sysfunc(dclose(&did));
%let rc=%sysfunc(filename(fileref));

%mend readraw;

options mprint;
%readraw(dir=c:\workshop\winsas\amacr);

Tuesday, February 2, 2010

Creating a Stored Macro Facility

options mstored sasmstore=macro;
libname macro '/home/dltmp/maclib';

%macro test / store des='This is my program';
         %let x=1;
%mend;

%copy test/source;

proc catalog cat=macro.sasmacr;
        contents;
run;

Link: http://www2.sas.com/proceedings/forum2008/101-2008.pdf

Tuesday, September 22, 2009

SYMGLOBL and SYMLOCAL

NOTE: Macro variable created inside the macro do loop is local, but can be changed to global by adding %global var after %do ...

%let c=yes;

%macro test;

%let d=yes;

data _null_;
      if symlocal ('c') then put '**** c is local';
      if symglobl('c') then put '**** c is global';
      if symlocal ('d') then put '**** d is local';
      if symglobl('d') then put '**** d is global';
run;

%mend test;
%test;

**** c is global
**** d is local

NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

Deleting a Macro Variable

NOTE: symdel will NOT work on local macro variable.

%let a=yes;

data _null_;
      if symexist('a') then put '**** a exists';
          call symdel('a');
      if symexist('a') then put '**** a still exists';
          else put '**** a doesnt exist';
run;

**** a exists
**** a doesnt exist

NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

SYMEXIST to check if a Macro Variable Exists

%let a=1;

data _null_;
      if symexist('a') then put '**** a exists';
          Else put '**** a doesnt exist';
      if symexist('b') then put '**** b exists';
          Else put '**** b doesnt exist';
run;

**** a exists
**** b doesnt exist

NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

Monday, September 7, 2009

Macro IN Operator (SAS 9.2)

In SAS 9.2 version:

%macro test;
%if &dsn IN ae ds co cm %then %do;
      Some---SAS—Statements;
%end;
%test;

Note:
No need of % sign in front of IN operator.
In SAS 9.2 both IN and # work if you use the system option minoperator inside your macro call.

%macro test/minoperator;
%if &dsn # ae ds co cm %then %do;
      Some---SAS—Statements;
%end;
%test;

%macro test;
%if &dsn IN ae ds co cm %then %do;
      Some---SAS—Statements;
%end;
%test;

MINOPERATOR option tells SAS to recognize the word 'IN' or special symbol # by the SAS macro facility as an infix operator when evaluating logical or integer expressions.

Here is another way of writing the macro code with delimiters.

Use MINDELIMITER option to change the default delimiter from space to any other, in this case it is comma (,).

options mindelimiter;

%macro test/mindelimiter=',';
%if &dsn IN ae,ds,co,cm %then %do;
      Some---SAS—Statements;
%end;
%test;

Tuesday, June 23, 2009

SYSPARM

Conditionally Execute Batch Jobs

data one;
      set one;
      if scan(sysparm(),1) ^= ' ' then do;
......

data _null_;
      array p{3} p1-p3;
      inp=sysparm();
      if inp='' then abort abend;
      do i = 1 to 3;
        p[i]=scan(inp,i);
      end;
      call symput('v1',left(trim(p1)));
......


sas program.sas -sysparm "XYZ ABC OPQ"

Sunday, June 14, 2009

Using Macros to Skip a Section of Code

Just put a “%macro name” at the top and a “%mend” at the end and never call the macro. This effectively comments out the code without running it. No need to worry about other comment styles in the code.

I. Statement Can Be Repeated Or Nested

SAS statements you want to execute.....
%macro SKIP ;
      SAS statements you want to skip.....
%mend SKIP ;

SAS statements you want to execute.....

%macro SKIP ;
      More SAS statements you want to skip.....
%mend SKIP ;
SAS statements you want to execute.....

II. Use NOSOURCE Option

Options Nosource;
%macro SKIP ;
      SAS statements you want to skip.....
%mend SKIP ;

Options Source;
SAS statements you want to execute.....