defmacro.html 5.64 KB
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>R: Define a macro</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../R.css">
</head><body>

<table width="100%" summary="page for defmacro {gtools}"><tr><td>defmacro {gtools}</td><td align="right">R Documentation</td></tr></table>
<h2>Define a macro</h2>


<h3>Description</h3>

<p>
<code>defmacro</code> define a macro that uses R expression replacement
</p>
<p>
<code>strmacro</code> define a macro that uses string replacement
</p>


<h3>Usage</h3>

<pre>
defmacro(..., expr)
strmacro(..., expr, strexpr)
</pre>


<h3>Arguments</h3>

<table summary="R argblock">
<tr valign="top"><td><code>...</code></td>
<td>
macro argument list </td></tr>
<tr valign="top"><td><code>expr</code></td>
<td>
R expression defining the macro body </td></tr>
<tr valign="top"><td><code>strexpr</code></td>
<td>
character string defining the macro body </td></tr>
</table>

<h3>Details</h3>

<p>
<code>defmacro</code> and <code>strmacro</code> create a macro from the expression
given in <code>expr</code>, with formal arguments given by the other
elements of the argument list.
</p>
<p>
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
<code>replacing</code> each formal argument by the expression
(<code>defmacro</code>) or string (<code>strmacro</code>) provided to the macro
call.
</p>
<p>
For <code>defmacro</code>, the special argument name <code>DOTS</code> will be
replaced by <code>...</code> in the formal argument list of the macro so
that <code>...</code>  in the body of the expression can be used to obtain
any additional arguments passed to the macro. For <code>strmacro</code> you
can mimic this behavior providing a <code>DOTS=""</code> argument.  This is
illustrated by the last example below.
</p>
<p>
Macros are often useful for creating new functions during code execution.
</p>


<h3>Value</h3>

<p>
A macro function.</p>

<h3>Note</h3>

<p>
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 <code>strmacro</code> and the C
preprocessor macros. For example, in
<pre>
  mul &lt;- defmacro(a, b, expr={a*b})
</pre>
a C programmer might expect
<code>mul(i, j + k)</code> to expand (incorrectly) to <code>i*j + k</code>. In fact it
expands correctly, to the equivalent of <code>i*(j + k)</code>.
</p>
<p>
For a discussion of the differences between functions
and macros, please Thomas Lumley's R-News article (reference below).
</p>


<h3>Author(s)</h3>

<p>
Thomas Lumley wrote <code>defmacro</code>.  Gregory R. Warnes
<a href="mailto:warnes@bst.rochester.edu">warnes@bst.rochester.edu</a> enhanced it and created
<code>strmacro</code>.
</p>


<h3>References</h3>

<p>
The original <code>defmacro</code> code was directly taken from:
</p>
<p>
Lumley T. "Programmer's Niche: Macros in {R}", R News, 2001, Vol 1,
No. 3, pp 11&ndash;13, <a href="http://CRAN.R-project.org/doc/Rnews/">http://CRAN.R-project.org/doc/Rnews/</a>
</p>


<h3>See Also</h3>

<p>
<code><a href="../../base/html/function.html">function</a></code>
<code><a href="../../base/html/substitute.html">substitute</a></code>,
<code><a href="../../base/html/eval.html">eval</a></code>,
<code><a href="../../base/html/parse.html">parse</a></code>,
<code><a href="../../base/html/source.html">source</a></code>,
<code><a href="../../base/html/parse.html">parse</a></code>,
</p>


<h3>Examples</h3>

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

# create example data using 999 as a missing value indicator
d &lt;- 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 &lt;- 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 &lt;- 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 &lt;- 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  &lt;- plot.sf(col='red',title='Red is more Fun!')
plot.blue &lt;- plot.sf(col='blue',title="Blue is Best!", lty=2)

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

</pre>



<hr><div align="center">[Package <em>gtools</em> version 2.4.0 <a href="00Index.html">Index]</a></div>

</body></html>