我希望实现的目标
所以我想在函数列表中获取函数的名称。
这里是一个例子:
foo = list(foo1 = sum, foo2 = mean)
我希望从foo
中提取的内容是:
list("sum", "mean")
我希望它是一个函数,意思是:
> foo = list(foo1 = sum, foo2 = mean)
> super_function(foo)
list("sum", "mean")
我检查过的内容
应用名称:
> sapply(foo , names)
$`foo1`
NULL
$foo2
NULL
应用deparse(substitute())
> my_f <- function(x)deparse(substitute(x))
> sapply(foo, my_f)
foo1 foo2
"X[[i]]" "X[[i]]"
这两个想法都不行。...
更多背景:
以下是更多详细信息。不需要他们理解第一个问题,而是社区询问了更多详细信息。
我将这些功能用作用户提供的聚合功能。
data(iris)
agg_function<-function(data, fun_to_apply){
res <- list()
for (col_to_transform in names(fun_to_apply)){
res[col_to_transform] <- (fun_to_apply[[col_to_transform]])(data[[col_to_transform]])
}
res
}
agg_function(iris, fun_to_apply = list("Sepal.Length" = mean, "Petal.Length" = sum))
结果是:
$`Sepal.Length`
[1] 5.843333
$Petal.Length
[1] 563.7
在此示例中,我对两列虹膜执行聚合。但是,我希望在结果的每个字段的名称中都包含执行函数的名称。 NB:这是我正在做的事情的过度简化;
结论:
您有什么想法吗?
答案 0 :(得分:2)
如果仅从列表foo = list(foo1 = sum, foo2 = mean)
开始,则不可能。对list()
的调用将评估返回变量sum
和mean
所指向的值的参数,但不会记住这些变量名。函数在R中没有名称。但是可以将函数分配给变量。但是,在R函数中,也可以不带名称。
您基本上已经创建了一个命名函数列表。可能也像这样
foo = list(foo1 = function(x) sum(x+1),
foo2 = function(x) mean(x+1))
这里我们也有函数,但是这些函数除了在列表中为它们指定的名称外,没有其他“名称”。
首先创建foo的唯一机会就是使用list()
之外的其他东西。或者让他们实际上在函数调用中显式调用list()
(这不是很实际)。
答案 1 :(得分:0)
尽管您已经说过tidyverse
不适合您,但我将其添加为另一个想法。
agg_function <- function(df, x, ...){
df %>%
summarise_at(.vars = x, funs(...))
}
agg_function(iris, c("Sepal.Length", "Petal.Length"), mean, sum)
Sepal.Length_mean Petal.Length_mean Sepal.Length_sum Petal.Length_sum
1 5.843333 3.758 876.5 563.7
答案 2 :(得分:0)
您可以使用带有字符串功能的列表
foo <- list(foo1 = "mean", foo2 = "sum")
foo
$foo1
[1] "mean"
$foo2
[1] "sum"
get(foo[[1]])(1:10)
[1] 5.5
get(foo[[2]])(1:10)
[1] 55
或者使用rlang
包并执行类似的操作
library(rlang)
foo <- quos(foo1 = mean, foo2 = sum)
getNames <- function(x) {
+ sapply(x, function(x) x[[2]])
+ }
getNames(foo)
$foo1
mean
$foo2
sum
eval_tidy(foo[[1]])(1:10)
[1] 5.5
eval_tidy(foo[[2]])(1:10)
[1] 55
这也适用于非命名函数
foo <- quos(foo1 = function(x) sum(x + 1), foo2 = sum)
getNames(foo)
$foo1
function(x) sum(x + 1)
$foo2
sum
eval_tidy(foo[[1]])(1:10)
[1] 65