【问题标题】:R : How evaluate formals (arguments) of function?R:如何评估函数的形式(参数)?
【发布时间】:2016-04-20 20:50:12
【问题描述】:

我真的找遍了整个地方,但没有找到我的问题的答案:

广义问题:

  • 如何在不启动 R 函数的情况下评估参数 (formals())?
  • 尽管 R 有“惰性评估”,您如何评估 R 中的整个环境?

我的问题:

我想获取 R 中任何函数的参数的计算时间。例如,让我们考虑一个函数:

foo <- function(x, arg1 = 2, arg2 = arg3[1], arg3 = rnorm(10^6)) {
  rnorm(10^7) # whatever time-consuming computation here
  arg3^2
  message("Too bad you had to launch the whole function !")
}

你会注意到困难:

  • 有些参数是必需的 (x),有些不是。 [结果:使用formals() 将不会返回未计算的 x 表达式!]
  • 一些参数是在另一个参数的函数中计算的,在它之后定义(arg2 是用 arg3 计算的)

想要的输出:

> system.time(foo(x=1))
Too bad you had to launch the whole function !
       user      system      elapsed 
      1.835       0.000       1.573 

> solution.function(foo, list(x=1))
The answer is in reality much lower ! It takes only 0.2 sec to compute the arguments !

【问题讨论】:

    标签: r functional-programming arguments lazy-evaluation


    【解决方案1】:

    基本上是一个 hack,但是复制你的函数

    g = foo
    

    用表达式替换函数的主体来评估每个参数,小心允许错误继续

    body(g) = quote(lapply(formals(), function(x) try(eval(x), TRUE))
    

    或许

    body(g) = quote(sapply(formals(), function(x) system.time(try(eval(x), TRUE))))
    

    评估g()(第一版)

    > g()
    $a
    [1] 2
    
    $b
    [1] 16
    
    $c
    [1] 16
    
    $d
    [1] 4
    
    $e
    [1] "Error in eval(expr, envir, enclos) : object 'unknown_variable' not found\n"
    attr(,"class")
    [1] "try-error"
    attr(,"condition")
    <simpleError in eval(expr, envir, enclos): object 'unknown_variable' not found>
    

    R 具有惰性求值,因此这不是衡量函数内部与外部时间的好方法。例如,f = function(y=Sys.sleep(Inf)) 1 立即返回而不是从不返回。

    必须单独处理 ... 参数。

    【讨论】:

    • 您的解决方案比我的要好得多。谢谢!
    • 实际上我刚刚意识到,当函数获得所需的参数时,这不起作用。我上传了一个非常接近的解决方案,也适用于这种情况。
    【解决方案2】:

    目前,我的工作区中确实有一个名为“c”的向量和一个名为“d”的数据框,所以我从以下渠道获得:

    lapply( formals(foo), eval)
    #---------
    $a
    [1] 2
    
    $b
    function (..., recursive = FALSE)  .Primitive("c")
    
    $c
          a  b a2 b2
    [1,]  1 NA  1 NA
    [2,]  4 NA  4 NA
    [3,]  9 NA  9 NA
    [4,] 16 NA 16 NA
    [5,] 25 NA 25 NA
    
    $d
    [1] 4
    
    Warning messages:
    1: In Ops.factor(left, right) : ‘^’ not meaningful for factors
    2: In Ops.factor(left, right) : ‘^’ not meaningful for factors
    

    这与您的EvalFormals 返回的内容不完全一样,但这似乎是我(一个经验丰富的 R 用户)所期望的。我无法理解与测量执行时间的可能联系。

    【讨论】:

      【解决方案3】:

      广义解

      很简单,as.list(environment) 似乎实际上评估了整个环境并返回了一个列表!

      我的最终解决方案

      在 Martin Morgan 的帮助下,我想出了这个解决方案,非常简单,并且处理了问题的所有约束:

      foo2 <- foo #Just copy/paste the function, before modifying it
      body(foo2) <- quote(as.list(environment())
      

      foo2(x=2) 将返回函数的所有参数(已评估)、所需参数(x)以及默认参数(arg1arg2arg3

      您可以检查:system.time(foo2(x=1)) 将返回 0.2 seconds ...仅启动 rnorm(10^6)

      【讨论】:

        猜你喜欢
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-01
        相关资源
        最近更新 更多