获取列表中的函数名称

时间:2018-08-01 13:34:13

标签: r

我希望实现的目标

所以我想在函数列表中获取函数的名称。

这里是一个例子:

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:这是我正在做的事情的过度简化;

结论:

您有什么想法吗?

3 个答案:

答案 0 :(得分:2)

如果仅从列表foo = list(foo1 = sum, foo2 = mean)开始,则不可能。对list()的调用将评估返回变量summean所指向的值的参数,但不会记住这些变量名。函数在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