Replace unvalued argument with multiple functions

Consider the following function foo

. I would like to write code na.rm = TRUE

in each of the calls in the list that returns a result, but I only want to write it once. My current implementation doesn't work.

foo <- function(x) {
    e <- expression(na.rm = TRUE)
    list(sum(x, eval(e)), mean(x, eval(e)), sd(x, eval(e)))
}

      

I don't want to use ...

in the argument list for this function. I don't want to give the user the option to add an argument na.rm

. The problem with the above code is that

> eval(expression(na.rm = TRUE))
# [1] TRUE

      

and therefore TRUE

passed to the argument trim

in mean

instead ofna.rm

> foo(c(1, NA, 3))
# Error in mean.default(x, eval(e)) : 'trim' must be numeric of length one

      

Is there a way to pass the argument as an expression, perhaps with quote

or substitute

, so that R will read the argument like na.rm = TRUE

instead of just TRUE

?

Note: My actual function uses quiet = TRUE

five times in seven lines, so the code would be cleaner if I could just write the expression once and pass it to each of the five functions.

+3


source to share


3 answers


I really don't know if this is a good idea anyway, but what you want to do can be done with do.call

:

foo <- function(x) {
  args <- list(quote(x),na.rm=TRUE)
  list(
    do.call(sum,args), 
    do.call(mean, args),
    do.call(sd, args)
  )
}

      

As Hadley said in the comments, you don't want to completely copy x

to the list args

as it can lead to memory problems when x

large. Hence using quote()

(thanks to Hadley)



This gives:

> foo(c(1, NA, 3))
[[1]]
[1] 4

[[2]]
[1] 2

[[3]]
[1] 1.414214

      

+4


source


You can exclude NA

before using functions:

foo <- function(x) {
    x2 <- na.omit(x)
    list(sum(x2), mean(x2), sd(x2))
}

      



Another possibility is to use lapply

with the functions you want to use:

foo <- function(x) {
   lapply(c(sum, mean, sd), function(f) f(x, na.rm = TRUE))
}

      

+3


source


You may try:

fun1 <- function(x) {
    lapply(c(sum, mean, sd), do.call, list(x, na.rm=TRUE))
}

fun1(c(1,NA,3))
#[[1]]
#[1] 4

#[[2]]
#[1] 2

#[[3]]
#[1] 1.414214

      

+3


source







All Articles