我需要遍历许多函数,并在函数名称旁边绘制/打印结果。我了解到(this question/answer)我必须使用substitute
/ eval
。如果每个函数名本身都包含在substitute()
中,则可以很好地工作(参见下面的(A)和(B))。有没有办法自动化这个,例如使用类似sapply
的结构? (C)明显失败,因为substitute
也包含了c()
条款,但也许有一些我错过了(D)的工作?还是其他任何想法?或者没有办法?
这就是我的尝试(小例子,真实代码有更多功能和绘图的东西)。
# A
x <- c(1:10)
my.fun <- substitute(mean) # works
print(paste(deparse(my.fun), ": ", eval(my.fun)(x), sep=""))
# B
for (my.fun in c(substitute(mean), substitute(median))) { # works, but lots of typing for longer function lists
print(paste(deparse(my.fun), ": ", eval(my.fun)(x), sep=""))
}
# C
for (my.fun in substitute(c(mean, median))) { # error: invalid for() loop sequence
print(paste(deparse(my.fun), ": ", eval(my.fun)(x), sep=""))
}
# D
for (my.fun in sapply(c(mean, median), substitute)) { # error: '...' used in an incorrect context
print(paste(deparse(my.fun), ": ", eval(my.fun)(x), sep=""))
}
# E # also not helpful
my.functions <- c(mean, median)
my.fun.2 <- NULL
for (i in 1:2) {
my.fun.2 <- c(my.fun.2, substitute(my.functions[i]))
}
# my.fun.2
# [[1]]
# my.functions[i]
# [[2]]
# my.functions[i]
答案 0 :(得分:1)
这个“单线”怎么样? :)
> x <- c(1:10)
> f <- function(...)
+ sapply(
+ sapply(
+ as.list(substitute(list(...)))[-1L],
+ deparse),
+ function(fn)
+ get(fn)(x))
> f(mean, median)
mean median
5.5 5.5
简而言之,您可以将函数作为多个参数传递,然后在逐个实际评估函数之前快速deparse
。所以上面的函数有一些额外的评论:
#' Evaluate multiple functions on some values
#' @param ... any number of function that will take \code{x} as the argument
#' @param x values to be passed to the functions
#' @examples
#' f(mean, median)
#' f(mean, median, sum, x = mtcars$hp)
f <- function(..., x = c(1:10)) {
## get provided function names
fns <- sapply(as.list(substitute(list(...)))[-1L], deparse)
## run each function as an anonymous function on "x"
sapply(fns, function(fn) get(fn)(x))
}
或者使用do.call
而不是后一个匿名函数:
f <- function(..., x = c(1:10)) {
## get provided function names
fns <- sapply(as.list(substitute(list(...)))[-1L], deparse)
## run each function on "x"
sapply(fns, do.call, args = list(x))
}