Home > Blockchain >  Function to apply mean on a list of vectors without need to list the vectors (changes to a function
Function to apply mean on a list of vectors without need to list the vectors (changes to a function

Time:05-28

I have multiple objects and I need to apply some function to them, in my example mean. But the function call shouldn't include list, it must look like this: my_function(a, b, d). Advise how to do it please, probably I need quote or substitute, but I'm not sure how to use them.

a <- c(1:15)
b <- c(1:17)
d <- c(1:19)
my_function <- function(objects) {
  lapply(objects, mean)
}
my_function(list(a, b, d))

CodePudding user response:

A possible solution:

a <- c(1:15)
b <- c(1:17)
d <- c(1:19)

my_function <- function(...) {
  lapply(list(...), mean)
}

my_function(a, b, d)

#> [[1]]
#> [1] 8
#> 
#> [[2]]
#> [1] 9
#> 
#> [[3]]
#> [1] 10

CodePudding user response:

To still be able to benefit from the other arguments of mean such as na.rm= and trim=, i.e. to generalize, we may match the formalArgs with the dots and split the call accordingly.

my_function <- function(...) {
  cl <- match.call()
  m <- match(formalArgs(base:::mean.default), names(cl), 0L)
  vapply(as.list(cl)[-c(1L, m)], function(x) {
    eval(as.call(c(quote(base:::mean.default), list(x), as.list(cl[m]))))
  }, numeric(1L))
}

## OP's example
my_function(a, b, d) 
# [1]  8  9 10


## generalization:
set.seed(42)
my_function(rnorm(12), rnorm(5), c(NA, rnorm(3)))
# [1]  0.7553736 -0.2898547         NA

set.seed(42)
my_function(rnorm(12), rnorm(5), c(NA, rnorm(3)), na.rm=TRUE)
# 0.7553736 -0.2898547 -1.2589363 

set.seed(42)
my_function(rnorm(12), rnorm(5), c(NA, rnorm(3)), na.rm=TRUE, trim=.5)
# 0.5185655 -0.2787888 -2.4404669 

Data:

a <- 1:15; b <- 1:17; d <- 1:19
  • Related