Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not passing all optional arguments in apply

Tags:

function

r

I am facing some problem with the apply function passing on arguments to a function when not needed. I understand that apply don't know what to do with the optional arguments and just pass them on the function.

But anyhow, here is what I would like to do:

First I want to specify a list of functions that I would like to use.

functions <- list(length, sum)

Then I would like to create a function which apply these specified functions on a data set.

myFunc <- function(data, functions) {
  for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]]))
}

This works fine.

data <- cbind(rnorm(100), rnorm(100))
myFunc(data, functions)

[1] 100 100
[1] -0.5758939 -5.1311173

But I would also like to use additional arguments for some functions, e.g.

power <- function(x, p) x^p 

Which don't work as I want to. If I modify myFunc to:

myFunc <- function(data, functions, ...) {
  for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]], ...))
}

functions as

functions <- list(length, sum, power)

and then try my function I get

myFunc(data, functions, p=2)

Error in FUN(newX[, i], ...) : 
  2 arguments passed to 'length' which requires 1

How may I solve this issue?

Sorry for the wall of text. Thank you!

like image 816
Pierre Avatar asked Apr 13 '15 20:04

Pierre


2 Answers

You can use Curry from functional to fix the parameter you want, put the function in the list of function you want to apply and finally iterate over this list of functions:

library(functional)

power <- function(x, p) x^p 
funcs = list(length, sum, Curry(power, p=2), Curry(power, p=3))
lapply(funcs, function(f) apply(data, 2 , f))

With your code you can use:

functions <- list(length, sum, Curry(power, p=2))
myFunc(data, functions)
like image 181
Colonel Beauvel Avatar answered Oct 14 '22 14:10

Colonel Beauvel


I'd advocate using Colonel's Curry approach, but if you want to stick to base R you can always:

funcs <- list(length, sum, function(x) power(x, 2))

which is roughly what Curry ends up doing

like image 20
BrodieG Avatar answered Oct 14 '22 14:10

BrodieG