defmacro               package:gtools               R Documentation

_D_e_f_i_n_e _a _m_a_c_r_o

_D_e_s_c_r_i_p_t_i_o_n:

     'defmacro' define a macro that uses R expression replacement

     'strmacro' define a macro that uses string replacement

_U_s_a_g_e:

     defmacro(..., expr)
     strmacro(..., expr, strexpr)

_A_r_g_u_m_e_n_t_s:

     ...: macro argument list 

    expr: R expression defining the macro body 

 strexpr: character string defining the macro body 

_D_e_t_a_i_l_s:

     'defmacro' and 'strmacro' create a macro from the expression given
     in 'expr', with formal arguments given by the other elements of
     the argument list.

     A macro is similar to a function definition, the arguments are
     handled.  In a function, formal arguments are simply variables
     that  contains the result of evaluating the expressions provided
     to the function call.  In contrast, macros actually modify the
     macro body by 'replacing' each formal argument by the expression
     ('defmacro') or string ('strmacro') provided to the macro call.

     For 'defmacro', the special argument name 'DOTS' will be replaced
     by '...' in the formal argument list of the macro so that '...' 
     in the body of the expression can be used to obtain any additional
     arguments passed to the macro. For 'strmacro' you can mimic this
     behavior providing a 'DOTS=""' argument.  This is illustrated by
     the last example below.

     Macros are often useful for creating new functions during code
     execution.

_V_a_l_u_e:

     A macro function.

_N_o_t_e:

     Note that because [the defmacro code] works on the parsed
     expression, not on a text string, defmacro avoids some of the
     problems of traditional string substitution macros such as
     'strmacro' and the C preprocessor macros. For example, in


       mul <- defmacro(a, b, expr={a*b})

     a C programmer might expect 'mul(i, j + k)' to expand
     (incorrectly) to 'i*j + k'. In fact it expands correctly, to the
     equivalent of 'i*(j + k)'.

     For a discussion of the differences between functions and macros,
     please Thomas Lumley's R-News article (reference below).

_A_u_t_h_o_r(_s):

     Thomas Lumley wrote 'defmacro'.  Gregory R. Warnes
     gregory.r.warnes@pfizer.com enhanced it and created 'strmacro'.

_R_e_f_e_r_e_n_c_e_s:

     The original 'defmacro' code was directly taken from:

     Lumley T. "Programmer's Niche: Macros in {R}", R News, 2001, Vol
     1, No. 3, pp 11-13, <URL: http://CRAN.R-project.org/doc/Rnews/>

_S_e_e _A_l_s_o:

     'function' 'substitute', 'eval', 'parse', 'source', 'parse',

_E_x_a_m_p_l_e_s:

     ####
     # macro for replacing a specified missing value indicator with NA
     # within a dataframe
     ###
     setNA <- defmacro(df, var, values,
                       expr={
                              df$var[df$var %in% values] <- NA
                            })

     # create example data using 999 as a missing value indicator
     d <- data.frame(
        Grp=c("Trt", "Ctl", "Ctl", "Trt", "Ctl", "Ctl", "Trt", "Ctl", "Trt", "Ctl"),
        V1=c(1, 2, 3, 4, 5, 6, 999, 8,   9,  10),
        V2=c(1, 1, 1, 1, 1, 2, 999, 2, 999, 999)
                    )
     d

     # Try it out
     setNA(d, V1, 999)
     setNA(d, V2, 999)
     d

     ###
     # Expression macro
     ###
     plot.d <- defmacro( df, var, DOTS, col="red", title="", expr=
       plot( df$var ~ df$Grp, type="b", col=col, main=title, ... )
     )

     plot.d( d, V1)
     plot.d( d, V1, col="blue" )
     plot.d( d, V1, lwd=4)  # use optional 'DOTS' argument

     ###
     # String macro (note the quoted text in the calls below)
     # 
     # This style of macro can be useful when you are reading
     # function arguments from a text file
     ###
     plot.s <- strmacro( DF, VAR, COL="'red'", TITLE="''", DOTS="", expr=
       plot( DF$VAR ~ DF$Grp, type="b", col=COL, main=TITLE, DOTS)
     )

     plot.s( "d", "V1")
     plot.s( DF="d", VAR="V1", COL='"blue"' ) 
     plot.s( "d", "V1", DOTS='lwd=4')  # use optional 'DOTS' argument


     #######
     # Create a macro that defines new functions
     ######
     plot.sf <- defmacro(type='b', col='black',
                         title=deparse(substitute(x)), DOTS, expr=
       function(x,y) plot( x,y, type=type, col=col, main=title, ...)
     )

     plot.red  <- plot.sf(col='red',title='Red is more Fun!')
     plot.blue <- plot.sf(col='blue',title="Blue is Best!", lty=2)

     plot.red(1:100,rnorm(100))
     plot.blue(1:100,rnorm(100))

