1% Generated by roxygen2: do not edit by hand
2% Please edit documentation in R/defmacro.R, R/strmacro.R
3\name{defmacro}
4\alias{defmacro}
5\alias{strmacro}
6\title{Define a macro}
7\usage{
8defmacro(..., expr)
9
10strmacro(..., expr, strexpr)
11}
12\arguments{
13\item{\dots}{macro argument list}
14
15\item{expr}{R expression defining the macro body}
16
17\item{strexpr}{character string defining the macro body}
18}
19\value{
20A macro function.
21}
22\description{
23\code{defmacro} define a macro that uses R expression replacement
24}
25\details{
26\code{strmacro} define a macro that uses string replacement
27
28
29\code{defmacro} and \code{strmacro} create a macro from the expression given
30in \code{expr}, with formal arguments given by the other elements of the
31argument list.
32
33A macro is similar to a function definition except for handling of formal
34arguments.  In a function, formal arguments are simply variables that
35contains the result of evaluating the expressions provided to the function
36call.  In contrast, macros actually modify the macro body by
37\emph{replacing} each formal argument by the expression (\code{defmacro}) or
38string (\code{strmacro}) provided to the macro call.
39
40For \code{defmacro}, the special argument name \code{DOTS} will be replaced
41by \code{...} in the formal argument list of the macro so that \code{...} in
42the body of the expression can be used to obtain any additional arguments
43passed to the macro. For \code{strmacro} you can mimic this behavior
44providing a \code{DOTS=""} argument.  This is illustrated by the last
45example below.
46
47Macros are often useful for creating new functions during code execution.
48}
49\note{
50Note that because [the defmacro code] works on the parsed expression,
51not on a text string, defmacro avoids some of the problems of traditional
52string substitution macros such as \code{strmacro} and the C preprocessor
53macros. For example, in \preformatted{ mul <- defmacro(a, b, expr={a*b}) } a
54C programmer might expect \code{mul(i, j + k)} to expand (incorrectly) to
55\code{i*j + k}. In fact it expands correctly, to the equivalent of
56\code{i*(j + k)}.
57
58For a discussion of the differences between functions and macros, please
59Thomas Lumley's R-News article (reference below).
60}
61\examples{
62
63####
64# macro for replacing a specified missing value indicator with NA
65# within a dataframe
66###
67setNA <- defmacro(df, var, values,
68  expr = {
69    df$var[df$var \%in\% values] <- NA
70  }
71)
72
73# create example data using 999 as a missing value indicator
74d <- data.frame(
75  Grp = c("Trt", "Ctl", "Ctl", "Trt", "Ctl", "Ctl", "Trt", "Ctl", "Trt", "Ctl"),
76  V1 = c(1, 2, 3, 4, 5, 6, 999, 8, 9, 10),
77  V2 = c(1, 1, 1, 1, 1, 2, 999, 2, 999, 999),
78  stringsAsFactors = TRUE
79)
80d
81
82# Try it out
83setNA(d, V1, 999)
84setNA(d, V2, 999)
85d
86
87
88###
89# Expression macro
90###
91plot.d <- defmacro(df, var, DOTS,
92  col = "red", title = "", expr =
93    plot(df$var ~ df$Grp, type = "b", col = col, main = title, ...)
94)
95
96plot.d(d, V1)
97plot.d(d, V1, col = "blue")
98plot.d(d, V1, lwd = 4) # use optional 'DOTS' argument
99
100###
101# String macro (note the quoted text in the calls below)
102#
103# This style of macro can be useful when you are reading
104# function arguments from a text file
105###
106plot.s <- strmacro(DF, VAR,
107  COL = "'red'", TITLE = "''", DOTS = "", expr =
108    plot(DF$VAR ~ DF$Grp, type = "b", col = COL, main = TITLE, DOTS)
109)
110
111plot.s("d", "V1")
112plot.s(DF = "d", VAR = "V1", COL = '"blue"')
113plot.s("d", "V1", DOTS = "lwd=4") # use optional 'DOTS' argument
114
115
116
117#######
118# Create a macro that defines new functions
119######
120plot.sf <- defmacro(
121  type = "b", col = "black",
122  title = deparse(substitute(x)), DOTS, expr =
123    function(x, y) plot(x, y, type = type, col = col, main = title, ...)
124)
125
126plot.red <- plot.sf(col = "red", title = "Red is more Fun!")
127plot.blue <- plot.sf(col = "blue", title = "Blue is Best!", lty = 2)
128
129plot.red(1:100, rnorm(100))
130plot.blue(1:100, rnorm(100))
131}
132\references{
133The original \code{defmacro} code was directly taken from:
134
135Lumley T. "Programmer's Niche: Macros in R", R News, 2001, Vol 1, No. 3, pp
13611--13, \url{https://cran.r-project.org/doc/Rnews/}
137}
138\seealso{
139\code{\link[base]{function}} \code{\link[base]{substitute}},
140\code{\link[base]{eval}}, \code{\link[base]{parse}},
141\code{\link[base]{source}}, \code{\link[base]{parse}},
142}
143\author{
144Thomas Lumley wrote \code{defmacro}.  Gregory R. Warnes
145\email{greg@warnes.net} enhanced it and created \code{strmacro}.
146}
147\keyword{##}
148\keyword{Code}
149\keyword{from}
150\keyword{programming}
151