假设我有一堆函数,每个函数都有MyFunction.1
等等。我想将这些函数传递给另一个函数,它打印出一个小报告。理想情况下,我希望能够标记报告的各个部分,通过这些部分使用函数来生成结果。
那么有没有什么好方法可以将预定义函数的名称作为字符串?
答案 0 :(得分:45)
我想要同样的事情,并且记得library(foo)
不需要引号,这就是它的作用:
package <- as.character(substitute(package))
答案 1 :(得分:16)
另一种方法是将函数的名称传递给报表函数,然后使用get()
命令自行获取函数。例如:
function.names <- c("which","all")
fun1 <- get(function.names[1])
fun2 <- get(function.names[2])
然后在原始字符向量中有名称,并且函数在您定义时具有新名称。在这种情况下,all
函数现在被称为fun2
:
> fun2(c(TRUE, FALSE))
[1] FALSE
或者,如果您真的想保留原始函数名称,只需使用assign函数在本地分配它们:
assign(function.names[2], get(function.names[2]))
如果您现在运行此命令,最终会在all
中使用".GlobalEnv"
功能。您可以使用ls()
来查看此内容。
答案 2 :(得分:7)
这可能会导致parse(eval(...))
此时您对此批评持开放态度:
R> library(fortunes)
R> fortune("parse")
If the answer is parse() you should usually rethink the question.
-- Thomas Lumley
R-help (February 2005)
R>
那么你的函数必须被称为MyFunction.1
等pp?
答案 3 :(得分:6)
您可以通过match.call
获取函数的未评估参数。例如:
> x <- function(y) print(match.call()[2])
> x(lm)
lm()
答案 4 :(得分:3)
只想提供一个示例来展示此问题的优势和局限性:
我想用其名称“保存”一个函数,作为另一个函数中使用的选项:
R> foreach(..., .combine=test_fun) {...}
test_fun
是函数的名称,当然还有
R> mode(test_fun)
[1] "function"
当我在foreach中使用它时,我只需要函数名称,而test_fun
可以是现有函数(例如cbind
)。因此,test_fun
由
R> test_fun <- get('cbind')
或
R> test_fun <- assign('cbind', get('cbind'))
所以,你得到了这里的功能
R> test_fun
function (..., deparse.level = 1)
.Internal(cbind(deparse.level, ...))
实际上,原始名称无法维护,因此您无法将test_fun
转换回字符串"cbind"
。
R> deparse(substitute(test_fun))
[1] "test_fun"
我遗憾地需要解析foreach代码,因此需要字符串中显示的原始名称。这意味着唯一的方法是将'cbind'
保存为字符串,并且在这种情况下创建这样的函数对象不会带来任何好处。
答案 5 :(得分:2)
当函数作为对象传递时,它会丢失其名称。例如,参见以下行的结果:
str(lm)
lm
您可以获取函数的参数和正文,但不能获取名称。
我的建议是构建一个命名的函数列表,其名称可以打印出来:
> somefns <- list(lm=lm, aggregate=aggregate)
> str(somefns)
List of 2
$ lm :function (formula, data, subset, weights, na.action, method = "qr",
model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
contrasts = NULL, offset, ...)
$ aggregate:function (x, ...)
> somefns[[1]](dist ~ speed, data=cars)
Call:
somefns[[1]](formula = dist ~ speed, data = cars)
Coefficients:
(Intercept) speed
-17.58 3.93
> names(somefns)[[1]]
[1] "lm"
答案 6 :(得分:2)
怎么样:
deparse(quote(foo.bar))
答案 7 :(得分:0)
@nfultz的观察很不错,因此该线程问题的答案将是:-
workingFunction <- Function(f)
{ functionName <- as.character(substitute(f)) }
或
workingFunction <- Function(f)
{ functionName <- deparse(substitute(f)) }
所有其他答案将仅返回参数名称本身(在上面的示例中为'f')-我一直在尝试使用它们,因为我一直在研究函数,并遇到了无法检索函数名称的问题在另一个函数内部,其中第一个函数在调用时作为参数传递给第二个函数。希望我的回答对所有可能坚持不变的人有所帮助!
答案 8 :(得分:0)
我在这个问题上也付出了很多努力,不幸的是,给定的解决方案对我来说并不奏效,但是我想出了一种用R6类来命名的方法。
这是一个最小的例子:
NameProvider <-
R6::R6Class(
"NameProvider",
base::list(
get_fun_name = function(fun_name) { return(fun_name)})
)
NameUser <-
R6::R6Class(
"NameUser",
base::list(
do_something = function(fun)
{
np <- NameProvider$new()
fname <- np$get_fun_name(fun_name = base::as.character(base::substitute(fun)))
do_the_thing <- paste0("THIS IS ", base::toupper(fname), "!!!")
return(do_the_thing)
}
)
)
nu <- NameUser$new()
nu$do_something(fun = mean)
类NameProvider
仅将名称作为字符串返回,并且在类NameUser
中调用base::as.character(base::substitute(...))
。