我有一系列功能,其中还包含一个用户定义的功能:
> fun <- function(x) {x}
> funs <- c(median, mean, fun)
是否可以从此列表中获取函数名称作为字符串?到目前为止,我唯一的解决方法是创建包含函数名称为vector的vector:
> fun.names <- c("median", "mean", "fun")
当我想获取变量名称时,我会使用这个技巧(如果这不正确请更正确),但是你可以看到它只适用于一个变量而不是列表:
> as.character(substitute(mean))
[1] "mean"
> as.character(substitute(funs))
[1] "funs"
是否还有适用于列表的内容?如果列表包含函数或数据类型,有什么区别吗?
修改 我需要将这个函数列表(加上另一个数据)传递给另一个函数。然后列表中的那些函数将应用于数据集。需要函数名,因为如果列表中有多个函数传递,我希望能够确定应用了哪个函数。到目前为止,我一直在使用它:
window.size <- c(1,2,3)
combinations <- expand.grid(window.size, c(median, mean))
combinations <- cbind(combinations, rep(c("median","mean"), each = length(window.size)))
答案 0 :(得分:2)
一般来说,这是不可能的。考虑funs
:
funs <- c(median,mean,function(x) x);
在这种情况下,根本没有与用户定义的功能相关联的名称。 R中没有规则表明所有函数必须在任何时间点绑定到名称。
如果你想开始对 和 所有这些lambdas的定义做出一些假设,那么可能会开启。
一个想法是在每个函数的闭包环境中搜索与函数本身匹配(相同)的条目,然后使用该名称。由于比较工作,这将导致性能损失,但如果您不必重复运行它,则可以容忍:
getFunNameFromClosure <- function(fun) names(which(do.call(c,eapply(environment(fun),identical,fun)))[1L]);
演示:
fun <- function(x) x;
funs <- c(median,mean,fun);
sapply(funs,getFunNameFromClosure);
## [1] "median" "mean" "fun"
<强>注意事项:强>
1:如前所述,这不适用于从未绑定到名称的函数。此外,它不适用于其闭包环境不包含对函数的绑定的函数。如果函数绑定到与其闭包不同的环境中的名称(通过返回值,超级赋值或assign()
调用)或者其闭包环境已明确更改,则可能会发生这种情况。
2:可以将函数绑定到多个名称。因此,eapply()
搜索得到的名称可能不是您期望的名称。这是一个很好的证明:
getFunNameFromClosure(ls); ## gets wrong name
## [1] "objects"
identical(ls,objects); ## this is why
## [1] TRUE
答案 1 :(得分:1)
这是一种hacky方法:
funs <- list(median, mean)
fun_names = sapply(funs, function(x) {
s = as.character(deparse(eval(x)))[[2]]
gsub('UseMethod\\(|[[:punct:]]', '', s)
})
names(funs) <- fun_names
funs
$median
function (x, na.rm = FALSE)
UseMethod("median")
<bytecode: 0x103252878>
<environment: namespace:stats>
$mean
function (x, ...)
UseMethod("mean")
<bytecode: 0x103ea11b8>
<environment: namespace:base>
combinations <- expand.grid(window.size, fun_names, c(median, mean))