Note: See edits below
R's ellipses or three dots feature is designed to handle optional arguments. This may be useful if your function will have more optional arguments. In the example you provided, structure the input arguments in the following way.
plot1 <- function(df, x, y, ...) {
}
To process the ... to look for a specific variable name can be a bit tricky, but using the functions eval, substitute, and alist can help with this. Adding the following lines will put the optional arguments into a list.
plot1 <- function(df, x, y, ...) {
args <- eval(substitute(alist(...)))
inputs <- purrr::map(args, as.list)
}
Note: requires purrr package.
To evaluate all optional arguments to look for a specific name, you can use a similar code as mentioned above. Here is the full example.
library(ggplot2)
plot1 <- function(df, x, y, ...) {
# eval inputs
args <- eval(substitute(alist(...)))
inputs <- purrr::map(args, as.list)
print(args)
print(inputs)
# define base plot
g <- ggplot(df, aes_string(x = x, y = y)) + geom_point()
# return chart with breaks only if optional arguments are present
# and if ybreaks exists
if (length(inputs) > 0 && !is.na(inputs$ybreak)) {
# rebuild seq
breaks <- inputs$ybreak
new_seq <- seq(breaks[[2]], breaks[[3]], by = breaks$by)
# add to chart
g <- g + scale_y_continuous(breaks = new_seq)
}
# return chart
return(g)
}
If you have more than one optional argument, nest the is.na(inputs$ybreak) condition in length(inputs) > 0. As the evaluation of optional arguments is only necessary if one or more optional arguments are submitted.
Depending on your function and how you intend to use it, you can use simpler methods such as:
plot1 <- function(df, x, y, ...) {
args <- list(ybreaks = ..1)
}
However, the previous method may be a better option for packages or production code.
For more information, see the Advanced R: Chapter 6 Functions
EDITS:
The original reply still stands. However, I would like to suggest an alternative method for processing optional arguments. The function list2 and dots_list from the rlang package are easier to use and allow for more control over the ellipsis .... For example the plot1 function would be restructured to:
plot1 <- function(df, x, y, ...) {
- args <- eval(substitute(alist(...)))
- inputs <- purrr::map(args, as.list)
+ args <- rlang::list2(...)
# evaluate arguments using
# args$my_optional_argument or
# args[["my_optional_argument"]]
}
Hope that helps!