41

I am writing function that involve other function from base R with a lot of arguments. For example (real function is much longer):

myfunction <- function (dataframe, Colv = NA) { 
matrix <- as.matrix (dataframe) 
out <- heatmap(matrix, Colv = Colv)
return(out)
}

data(mtcars)

myfunction (mtcars, Colv = NA)

The heatmap has many arguments that can be passed to:

heatmap(x, Rowv=NULL, Colv=if(symm)"Rowv" else NULL,
        distfun = dist, hclustfun = hclust,
        reorderfun = function(d,w) reorder(d,w),
        add.expr, symm = FALSE, revC = identical(Colv, "Rowv"),
        scale=c("row", "column", "none"), na.rm = TRUE,
        margins = c(5, 5), ColSideColors, RowSideColors,
        cexRow = 0.2 + 1/log10(nr), cexCol = 0.2 + 1/log10(nc),
        labRow = NULL, labCol = NULL, main = NULL,
        xlab = NULL, ylab = NULL,
        keep.dendro = FALSE, verbose = getOption("verbose"), ...)

I want to use these arguments without listing them inside myfunction.

myfunction (mtcars, Colv = NA, col = topo.colors(16))
Error in myfunction(mtcars, Colv = NA, col = topo.colors(16)) : 
  unused argument(s) (col = topo.colors(16))

I tried the following but do not work:

myfunction <- function (dataframe, Colv = NA) { 
matrix <- as.matrix (dataframe) 
out <- heatmap(matrix, Colv = Colv, ....)
return(out)
}
data(mtcars)

myfunction (mtcars, Colv = NA, col = topo.colors(16))
zx8754
  • 52,746
  • 12
  • 114
  • 209
jon
  • 11,186
  • 19
  • 80
  • 132

2 Answers2

44

Try three dots instead of four, and add the ellipsis argument to the top level function:

myfunction <- function (dataframe, Colv = NA, ...) { 
    matrix <- as.matrix (dataframe) 
    out <- heatmap(matrix, Colv = Colv, ...)
    return(out)
}
joran
  • 169,992
  • 32
  • 429
  • 468
  • 3
    Just to add an option (or add confusion), you can augment the contents of `...` by setting a variable inside your main function `dotfuns<-list(..., other_variable)` and passing that to subsequent functions. Do this at your own risk :-) – Carl Witthoft Jun 17 '12 at 18:38
  • @CarlWitthoft sorry I could not get what you mean, could exand your solution (perhaps as answer ) – jon Jun 17 '12 at 19:21
  • It wasn't an answer to your specific problem, just a comment on other things that can be done with the `...` collection of arguments. – Carl Witthoft Jun 17 '12 at 23:57
  • 2
    this answer is very helpful, I wonder if there is a solution when you have 2 different functions with different names of arguments – Dimitrios Zacharatos Jan 15 '20 at 16:10
  • 1
    @DimitriosZacharatos when you have **2 or more** different functions within your function you can specify lists of arguments, have a look at G. Grothendieck answer to [this question](https://stackoverflow.com/questions/25376197/split-up-arguments-and-distribute-to-multiple-functions). – Alf Pascu May 03 '22 at 16:48
0

Try this:

  • arguments for heatmap in globalenv:
argsHeat = alist( <arguments for heatmap>)
  • Instead of calling heatmap() inside myfunction, do this
out = do.call('heatmap', args = argsHeat)