考虑以下函数foo
。我想将na.rm = TRUE
硬编码到列表中返回结果的每个调用中,但我只想写一次。我当前的实现不起作用。
foo <- function(x) {
e <- expression(na.rm = TRUE)
list(sum(x, eval(e)), mean(x, eval(e)), sd(x, eval(e)))
}
我不想在此函数的参数列表中使用...
。我不想让用户选择添加na.rm
参数。上面代码的问题是
> eval(expression(na.rm = TRUE))
# [1] TRUE
因此TRUE
传递给trim
中的mean
参数,而不是na.rm
> foo(c(1, NA, 3))
# Error in mean.default(x, eval(e)) : 'trim' must be numeric of length one
有没有办法将参数作为表达式传递,可能使用quote
或substitute
,以便R将参数读为na.rm = TRUE
而不只是TRUE
?
注意:我的实际功能是在七行中使用quiet = TRUE
五次,所以如果我只能编写一次表达式,并将其传递给每个代码,代码就会更清晰五个功能。
答案 0 :(得分:4)
在任何情况下,我都不知道这是否是一个好主意,但您可以使用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)
)
}
正如哈德利在评论中所说,你不想完全在列表x
中复制args
,因为当x
很大时,这可能会导致内存问题。因此使用quote()
(thx Hadley)
这给出了:
> foo(c(1, NA, 3))
[[1]]
[1] 4
[[2]]
[1] 2
[[3]]
[1] 1.414214
答案 1 :(得分:3)
您可以在使用这些功能之前排除NA
:
foo <- function(x) {
x2 <- na.omit(x)
list(sum(x2), mean(x2), sd(x2))
}
另一种可能性是将lapply
与您要使用的功能一起使用:
foo <- function(x) {
lapply(c(sum, mean, sd), function(f) f(x, na.rm = TRUE))
}
答案 2 :(得分:3)
你可以尝试:
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