4

I use the dplyr package in R. Using that i want to create a function like

require(dplyr)
aFunction <- function(x, optionalParam1="abc"){
    cat(optionalParam1, "\n")
    return(x)
}
myFun <- function(data, ...){
    result <- data %>% mutate_each(funs(aFunction(., ...)))
}

and then call it like

data = data.frame(c1=c(1,2,3), c2=c(1,2,3))
myFun(data) # works
myFun(data, optionalParam1="xyz") # doesn't work

when calling myFun all optional parameters should be passed on to aFunction. But instead the error '...' used in an incorrect context is thrown.

This is the same function without dplyr which works as it should work...

myFun2 <- function(data, ...){
    for(c in colnames(data)){
        data[,c] = aFunction(data[,c], ...)
    }
}

how can I achieve the same result with dplyr?

Jonas
  • 1,639
  • 1
  • 18
  • 29
  • you are using a very abstract and contrieved example, what do you need this for and what are you trying to achieve? without this information all I can say is read about function operators in hadleys book and drown in the complexity of R's scoping rules madness: http://adv-r.had.co.nz/Function-operators.html – grrgrrbla Jun 10 '15 at 13:01
  • @grrgrrbla with `Curry` from the `functional` package you can get this working quite straightforwardly. See my answer below. – Paul Hiemstra Jun 10 '15 at 13:16
  • thanks :), I am always happy to learn new stuff! if you have any links or suggestions on where to learn more that would be awesome! – grrgrrbla Jun 10 '15 at 13:17
  • @grrgrrbla but the article on function operators also looks quite interesting. – Paul Hiemstra Jun 10 '15 at 13:18

1 Answers1

4

The mutate_each function simply does not interpret additional parameters as parameters to pass on to the function. So, once you pass it to mutate_each, the optional argument needs to be set. You can do this using a functional programming strategy called currying. Essentially, you create a new function, where the default value of optionalParam1 is changed. You can do this using the Curry function form the functional package.

aFunction <- function(x, optionalParam1="abc"){
    cat(optionalParam1, "\n")
    return(x)
}

myFun <- function(data, ...){
    require(functional)
    special_aFunction = Curry(aFunction, ...)
    result <- data %>% mutate_each(funs(special_aFunction))
}

> data = data.frame(c1=c(1,2,3), c2=c(1,2,3))
> myFun(data)
abc 
abc 
> myFun(data, optionalParam1="xyz") # now works
xyz 
xyz 
Community
  • 1
  • 1
Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149