这是我的R代码.功能定义为:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, T, f=f) {
exp(-f(x) / T)
}
test <- function(g=g, T=1) {
g(1, T)
}
Run Code Online (Sandbox Code Playgroud)
运行错误是:
> test()test()中的
错误:
承诺已经在评估中:递归默认参数引用或早期问题?
如果我替代的定义f在的g,那么错误消失.
我想知道错误是什么?如何纠正它,如果没有替代的定义f在的g?谢谢!
更新:
谢谢!两个问题:
(1)如果函数test进一步论证f,你会添加类似的东西test <- function(g.=g, T=1, f..=f){ g.(1,T, f.=f..) }吗?在递归更多的情况下,添加更多是一个好的和安全的做法.?
(2)if f是非函数参数,例如,g <- function(x, T, f=f){ exp(-f*x/T) }并且test <- function(g.=g, T=1, f=f){ g.(1,T, f=f.) },对于正式和实际的非功能性参数使用相同的名称是一个好的和安全的做法,还是会引起一些潜在的麻烦?
G. *_*eck 142
形式的正式论证x=x导致了这一点.消除它们出现的两个实例,我们得到:
f <- function(x, T) {
10 * sin(0.3 * x) * sin(1.3 * x^2) + 0.001 * x^3 + 0.2 * x + 80
}
g <- function(x, T, f. = f) { ## 1. note f.
exp(-f.(x)/T)
}
test<- function(g. = g, T = 1) { ## 2. note g.
g.(1,T)
}
test()
## [1] 8.560335e-37
Run Code Online (Sandbox Code Playgroud)
rrr*_*rrr 12
如前所述,问题来自于将函数参数定义为自身。但是,我想解释一下为什么这是一个问题,因为理解使我找到了一种更简单(对我而言)避免问题的方法:只需在调用中指定参数而不是定义。
这不起作用:
x = 4
my.function <- function(x = x){}
my.function() # recursive error!
Run Code Online (Sandbox Code Playgroud)
但这确实有效:
x = 4
my.function <- function(x){}
my.function(x = x) # works fine!
Run Code Online (Sandbox Code Playgroud)
函数参数存在于它们自己的本地环境中。
R 首先在本地环境中查找变量,然后在全局环境中查找。这就像函数内部的变量如何与全局环境中的变量具有相同的名称,而 R 将使用本地定义。
让函数参数定义形成它们自己的本地环境,这就是为什么您可以基于其他参数值拥有默认参数值的原因,例如
my.function <- function(x, two.x = 2 * x){}
Run Code Online (Sandbox Code Playgroud)
所以这就是为什么你不能定义一个函数,my.function <- function(x = x){}但是你可以使用my.function(x = x). 当您定义函数时,R 会感到困惑,因为它发现参数x =是 的本地值x,但是当您调用函数时,R 会在您调用x = 4的本地环境中找到。
因此,除了通过更改参数名称或显式指定其他答案中提到的环境来修复错误之外,您还可以仅x=x在调用函数时而不是在定义函数时指定。对我来说,x=x在调用中指定是最好的解决方案,因为它不涉及额外的语法或积累越来越多的变量名称。
如果指定参数评估上下文,则可以避免出现同名问题:
f <- function(x) {
10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, t=1, f=parent.frame()$f) {
exp(-f(x) / t)
}
test <- function(g=parent.frame()$g, t=1) {
g(1,t)
}
test()
[1] 8.560335e-37
Run Code Online (Sandbox Code Playgroud)