【问题标题】:R: find the original name of a function passed as argumentR:查找作为参数传递的函数的原始名称
【发布时间】:2015-07-06 19:31:39
【问题描述】:

我有函数 f1f2 将函数作为参数,例如:

f1 <- function(FUN) {
    ...
}


f2 <- function(FUN)  {
   f1(FUN=FUN)
}

从函数f1内部,我需要找回传递给f2的函数的原始名称,例如"myFunc",而不是"FUN"

基本上我们可以想象一个函数f1 使得f2(f1(mean)) 返回"mean"?如果FUN 是匿名的,我们可以例如返回NULLNA

在 R 中是否有一种简单/标准的方法可以做到这一点?我尝试使用手动搜索相同的功能代码(但它不是很干净,我正在寻找更好的解决方案)

fn = unlist(as.list(lsf.str(envir=.GlobalEnv)))
for (f in fn) {
    if (setequal(paste(body(myFunc)),paste(body(f)))) { 
      return(f)
    }
}

【问题讨论】:

  • 这里没有足够的信息。您需要创建一个可重现的示例。如果FUN 应该是一个函数,它可能是匿名的。在这种情况下应该返回什么?
  • @Roland 基本上我们可以想象一个函数f1 使f2(f1(mean)) 返回“平均值”吗?如果 FUN 是匿名的,我们可以例如返回 NULL 或 NA。我根据您的反馈修改了问题

标签: r function argument-passing


【解决方案1】:

在大多数情况下,以下函数会给出原始名称。

find.original.name <- function(fun) {
    objects <- ls(envir = environment(fun))
    for (i in objects) {
        if (identical(fun, get(i, envir = environment(fun)))) {
            return(i)
        }
    }
}

a <- ls
find.original.name(a)
# [1] ls

a <- glm
find.original.name(a)
# [1] "glm"

a <- function() print("test")
find.original.name(a)
# [1] "a"

但是如果一个函数的副本(准确的说不是副本)和原函数在同一个环境下,这个函数就不能正常工作了……

test <- function() print("test")
a <- test
find.original.name(a)
# [1] "a"

【讨论】:

    【解决方案2】:

    您也可以使用lazyeval 包:

    f1 <- function(FUN) {
      lazyeval::expr_text(FUN)
    }
    
    
    f2 <- function(FUN)  {
      f1(FUN = FUN)
    }
    
    f2(f2(f2(mean)))
    [1] "f2(f2(mean))"
    

    这对我有用:

    f1 <- function(FUN) {
      eval(quote(substitute(FUN)), envir = parent.frame())
    }
    
    
    f2 <- function(FUN)  {
      f1(FUN=FUN)
    }
    
    f2(mean)
    

    在这种情况下,f1 在 f2 环境中评估 substitute(FUN) 调用。

    查看这些结果:

    > f2(mean)
    mean
    > f2(function(x) {NULL})
    function(x) {
      NULL
    }
    

    如果要输出为字符串,则需要使用deparse,则可以定义f1:

    f1 <- function(FUN) {
      eval(quote(deparse(substitute(FUN))), envir = parent.frame())
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 2013-08-25
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 2019-04-02
      • 2020-01-13
      相关资源
      最近更新 更多