R:如何评估函数的形式(参数)?

时间:2016-01-15 09:32:02

标签: r functional-programming arguments lazy-evaluation

我真的很满意,并且没有找到我的问题的答案:

广义问题:

  • 如何评估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 !

3 个答案:

答案 0 :(得分:4)

基本上是黑客,但要复制你的功能

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立即返回而不是永远。

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

答案 1 :(得分:1)

广义解决方案

很简单,似乎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)以及默认参数(arg1arg2,{ {1}})

您可以查看:arg3将返回system.time(foo2(x=1)) ...仅启动0.2 seconds

答案 2 :(得分:1)

目前我的工作区中有一个名为'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用户)预期的结果。我没有意识到测量执行时间的可能性。