























Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Examples of macro programming in sas, including the implementation of the trapezoidal rule for numerical integration and the concatenation of data sets. The trapezoidal rule is used to estimate the area under a curve, while the concatenation of data sets combines multiple data sets into one. The document also demonstrates the use of macro variables, arrays, loops, and conditional logic.
Typology: Study notes
1 / 31
This page cannot be seen from the preview
Don't miss anything!
























From: Chapter 9 - MACRO programming
9.0 What is a macro and why would you use it?
Q: Why learn more about this text processor?
A: You are executing the same programs with minor
modification with some regularity.
9.1 Motivation for Macros: numerical integration to determine
P(0<Z<1.645)
Trapezoidal rule approximates the area under a curve, f(x), over
some specified limits of integrations, say “low” and “high”, by
summing the areas of a collection of adjacent trapezoids
constructed for a collection of points [ x 1 , f(x1) ] [ x2,f(x2) ], … ,
[ x (^) k,f(xk) ] where x 1 =”low”< x 2 < … < xk-1 < xk =”high” (see Burden
and Faires (1989) for more description of numerical integration
methods).
Obs ii low High incr area_est xout Yout
[Q] could you modify this program to have vertical lines
connecting the density values to the x-axis and connect the
density values to display the trapezoids being summed to obtain
the estimated area? It would be even cooler to superimpose the
true density.
Display 9.4: Output containing the [ x,f(x) ] values used in the
trapezoidal rule estimated of P(0<Z<1.645)
Plot of function values vs. x-values
A number of questions arise at this point. We have a very
specific implementation for a particular problem. What might
you want to do now?
Q (^) 1: How hard would it be to modify this code if we wanted
k =50 points vs. k =25 points?
Q (^) 2: Could we generalize this code to specify different limits
of integration?
Q (^) 3: Could we set up a “switch” to produce graphics only
when requested?
Q (^) 4: Is it possible to package this estimator into a callable
“subroutine” or “function?”
Q (^) 5: Could we generalize this code for any arbitrary (corrected
coded) function?
9.2 Macro processing
and this interchange will continue until the input stack has been
completely processed. This will be clearer when we look at how
code with macro statements and variables are resolved.
9.3 Macro variables, parameters and functions
A macro variable …
data lines that are being read into SAS).
stored in either local or global symbol tables.
is named using a valid SAS name
is preceded by an & when it is referenced in a SAS program.
if it follows text, then it is referenced as text¯o-
variable.
the value from text, i.e. ¯o-variable.text.
define others, so-called “user-defined macro variables.”
How will you usually start using MACROS in SAS?
A: most likely use macro variables to define simple
substitutions in a program. In Display 9.5, we modify the
trapezoidal numerical integration routine to address Q 1 and Q (^2)
from above -
Q 1 : How hard would it be to modify this code if we
wanted k =50 points vs. k =25 points?
Q 2 : Could we generalize this code to specify different
limits of integration?
Use %LET to assign values to macro variables NPTS (the macro
variable for k ), along with LOW and HIGH (the macro variables
that correspond to the limits of integration).
Display 9.5: Replacing the limits of integration and number of
points to evaluation in a trapezoidal rule estimation of
P(low < Z < high).
equivalent statements of the DO-END data step statements, here
%DO and %END.
9.4 Conditional execution, looping and macros
program, in so-called “open code.”
%then, can only be used in the context of a defined macro.
the macro processor when invoked. The general construction
of a macro involves the declaration of the macro along with
any variables that might be passed to it, the statements that are
to be invoked in the macro, and statement declaring the end of
the macro. In particular, a macro program looks like the
following
which is invoked by a reference to %prog-name omitting the
“;” here. The semi-colon is not needed. The %prog-name is
talking to the macro processor, not to other SAS components.
Parameters can be passed to macro programs. (Parameter has technical
First macro programming example: we explore complicated
macro variable constructions. Consider the example in Display 9.8 in which two
%showvalue(variable=var1, obs=time1) Value of '&variable' = var Value of '&obs' = time Value of '&&&variable&obs' = week
Macro defined below (trap_area_Z):
As part of the trap_area_Z macro construction, we explicitly
address the two questions:
Q 3 : Could we set up a “switch” to produce graphics only
when requested?
Q 4 : Is it possible to package this estimator into a callable
“subroutine” or “function?”
We start with the naming of this macro along with input
parameters. These input parameters are assigned default values
in the macro declaration.
to this macro. These comments begin with a %* and end with a
semi-colon. (Aside: Now if you used standard comments, e.g. start with an asterisk and
Display 9.10: Macro for constructing a trapezoidal rule estimate
of the area under a standard normal curve
%ncheck(1) Value of '&npts' = 1 %ncheck(-2) ERROR: '&npts' must exceed 1 ERROR: value of '&npts' = - %ncheck(0.5) ERROR: '&npts' must exceed 1 ERROR: value of '&npts' = 0.
We started with 5 questions. We have not yet addressed the 5
question: Q (^) 5: Could we generalize this code for any arbitrary
(corrected coded) function? We will not work through it here;
however, here is a hint to try at home. Where in the code is the
standard normal density function defined? Could you define a
macro variable that would contain this arbitrary function and
pass it as a parameter to some general trap_area macro?
Would you need to change more than one line in the macro
above?
As a final remark, if you were producing this as a macro that
would be used in a production environment, then you would
need to add checks for valid parameter values. How would you
do this in the trap_area_Z macro?
Now, I could claim that this code matches my first attempt at
constructing this macro; however, that would be a lie. Alas, the
truth is that debugging and error correction was required. The
next section touches on some basic strategies for exploring and
debugging errors in macro coding.
9.5. Debugging macro coding and programming
The first place to start exploring non-working macro code is to
write out the contents or values of macro variables.
you have defined using the statement %PUT ¯o-var-
name.
automatic;), the user-defined macros (%PUT user;)
or both types (%PUT all;). For debugging, either
specifying particular macro variables or all user-defined macro
variables would be more useful.
defined by SAS (you might be interested in using some of these
variables in your programs). The SYSDATE, SYSDAY,
SYSTIME are useful for extracting date and time information
while SYSLAST is useful for defining a default data set use in a
macro.
Display 9.13 includes a request to display the values of macro
variables that are automatically defined in SAS.
656 %put automatic; AUTOMATIC SYSDATE 06JUL AUTOMATIC SYSDATE9 06JUL AUTOMATIC SYSDAY Sunday AUTOMATIC SYSDSN WORK TRAPPER AUTOMATIC SYSERR 0 AUTOMATIC SYSLAST WORK.TRAPPER AUTOMATIC SYSPROCNAME GPLOT AUTOMATIC SYSTIME 09: AUTOMATIC SYSVER 9.
There are three main “options” that are useful for constructing
and debugging macros, namely, macrogen mprint
mlogic.
SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable LOW resolves to 0 SYMBOLGEN: Macro variable HIGH resolves to 1. SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable ODS_ON resolves to FALSE SYMBOLGEN: Macro variable PRINT_EST resolves to FALSE
NOTE: The file "C:\Users\baileraj\BAILERAJ\BOOK-stat-prog-may05\ch-09\est3.out" is: Filename=C:\Users\baileraj\BAILERAJ\BOOK-stat-prog-may05\ch-09\est3.out, RECFM=V,LRECL=256,File Size (bytes)=757, Last Modified=06Jul2008:10:39:57, Create Time=02Jul2008:15:41:
NOTE: 1 record was written to the file "C:\Users\baileraj\BAILERAJ\BOOK-stat-prog-may05\ch- 09\est3.out". The minimum record length was 54. The maximum record length was 54. NOTE: The data set WORK.TRAPPER has 1 observations and 17 variables. NOTE: DATA statement used (Total process time): real time 0.03 seconds cpu time 0.03 seconds
SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable NPTS resolves to 5 SYMBOLGEN: Macro variable PRINT_PTS resolves to FALSE SYMBOLGEN: Macro variable DISPLAY_GRAPH resolves to TRUE
NOTE: There were 1 observations read from the data set WORK.TRAPPER. NOTE: The data set WORK.TRAPPER2 has 5 observations and 20 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds
SYMBOLGEN: Macro variable ODS_ON resolves to FALSE
NOTE: There were 5 observations read from the data set WORK.TRAPPER2. NOTE: PROCEDURE GPLOT used (Total process time): real time 0.47 seconds cpu time 0.32 seconds
MPRINT(TRAP_AREA_Z): data trapper; MPRINT(TRAP_AREA_Z): file "C:\Users\baileraj\BAILERAJ\BOOK-stat-prog-may05\ch- 09\est3.out" MOD; MPRINT(TRAP_AREA_Z): retain trapsum 0; MPRINT(TRAP_AREA_Z): array x_value(5) x1-x5; MPRINT(TRAP_AREA_Z): array f_value(5) y1-y5; MPRINT(TRAP_AREA_Z): low = 0; MPRINT(TRAP_AREA_Z): high = 1.96; MPRINT(TRAP_AREA_Z): incr = (high-low)/( 5 -1); MPRINT(TRAP_AREA_Z): pi = arcos(-1); MPRINT(TRAP_AREA_Z): do i= 1 to 5; MPRINT(TRAP_AREA_Z): x_value[i] = low + incr(i-1); MPRINT(TRAP_AREA_Z): f_value[i] = (1/sqrt(2pi))exp(-x_value[i]x_value[i]/2); MPRINT(TRAP_AREA_Z): if i=1 or i=5 then trapsum = trapsum + f_value[i]/2; MPRINT(TRAP_AREA_Z): else trapsum = trapsum + f_value[i]; MPRINT(TRAP_AREA_Z): end;
MPRINT(TRAP_AREA_Z): data trapper; MPRINT(TRAP_AREA_Z): file "C:\Users\baileraj\BAILERAJ\BOOK-stat-prog-may05\ch-09\est3.out" MOD; MPRINT(TRAP_AREA_Z): retain trapsum 0; MPRINT(TRAP_AREA_Z): array x_value(5) x1-x5; MPRINT(TRAP_AREA_Z): array f_value(5) y1-y5; MPRINT(TRAP_AREA_Z): low = 0; MPRINT(TRAP_AREA_Z): high = 1.96; MPRINT(TRAP_AREA_Z): incr = (high-low)/( 5 -1); MPRINT(TRAP_AREA_Z): pi = arcos(-1); MPRINT(TRAP_AREA_Z): do i= 1 to 5; MPRINT(TRAP_AREA_Z): x_value[i] = low + incr(i-1); MPRINT(TRAP_AREA_Z): f_value[i] = (1/sqrt(2pi))exp(-x_value[i]x_value[i]/2); MPRINT(TRAP_AREA_Z): if i=1 or i=5 then trapsum = trapsum + f_value[i]/2; MPRINT(TRAP_AREA_Z): else trapsum = trapsum + f_value[i]; MPRINT(TRAP_AREA_Z): end; MPRINT(TRAP_AREA_Z): area_est = trapsum*incr; MPRINT(TRAP_AREA_Z): output;