Search code examples
rfunctionplotellipsis

How to use ellipsis (`...`) when defining functions in R


I knew ... permits user to input the parameters arbitrary. However, I have some further questions about how to use ... when defining a new function in R. Here are the examples:

data <- 1:10

PLOT <- function(data, ...){
par(mfrow = c(1, 2)

# Figure1
plot(data, ...)

# Figure2
plot(data, ...)
}

PLOT(data = data, col = "red")

The outcome is figure1 with red points and figure2 with red points. Here are the following questions:

  1. I would like to adjust figure1 and figure2 separately (e.g., figure1 in red points and figure2 in blue points), How can I do?

  2. I have many arguments to adjust, some of them adjust only figure1, some of them adjust only figure2, and some of them adjust both (e.g., figure1 in red with dash line; figure2 in blue with solid line; and both figures should have title of "Testing" and no x axis), how can I do?

I have googled and test different ways to code. However, I can't figure out how to do. I expect to see an answer with an explanation of the usage of ... and example codes. Thanks for the help!


Solution

  • You can't use dots to pass multiple arguments with the same name to different function calls. The normal way round this is to pass a list with the additional arguments for each function call:

    data <- 1:10
    
    PLOT <- function(data, fig1_args = list(), fig2_args = list()) {
      par(mfrow = c(1, 2))
          
          # Figure1
          do.call("plot", c(list(x = data), fig1_args))
          
          # Figure2
          do.call("plot", c(list(x = data), fig2_args))
    }
    
    PLOT(data = data, fig1_args = list(col = "red"), fig2_args = list(col = "blue"))
    

    enter image description here

    The alternative if you only need to be able to change one or two aspects of each plot is to have a specific copy of each parameter:

    PLOT <- function(data, col1 = 'black', col2 = 'black') {
      par(mfrow = c(1, 2))
          
          # Figure1
          plot(data, col = col1)
          
          # Figure2
          plot(data, col = col2)
    }
    
    PLOT(data = data, col1 = 'red', col2 = 'blue')
    

    enter image description here

    This doesn't scale well if you want to preserve the ability to change many different features of each plot.