我真的很满意,并且没有找到我的问题的答案:
广义问题:
formals()
),而不启动它?我的问题:
我想得到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 !
答案 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
)以及默认参数(arg1
,arg2
,{ {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用户)预期的结果。我没有意识到测量执行时间的可能性。