defmacro: Define a macro

View source: R/defmacro.R

defmacroR Documentation

Define a macro


defmacro define a macro that uses R expression replacement


defmacro(..., expr)

strmacro(..., expr, strexpr)



macro argument list


R expression defining the macro body


character string defining the macro body


strmacro define a macro that uses string replacement

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 except for handling of formal arguments. 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.


A macro function.


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).


Thomas Lumley wrote defmacro. Gregory R. Warnes enhanced it and created strmacro.


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,

See Also

function substitute, eval, parse, source, parse,


# 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),
  stringsAsFactors = TRUE

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

# 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.sf(col = "red", title = "Red is more Fun!") <- plot.sf(col = "blue", title = "Blue is Best!", lty = 2), rnorm(100)), rnorm(100))

gtools documentation built on Nov. 28, 2022, 1:09 a.m.