R 函数的调试优化

R 函数的调试优化,r,function,optimization,R,Function,Optimization,我有一个函数,当被要求计算-logLik给定参数时,它工作得很好。但是,如果我尝试优化函数,它会返回一条错误消息。我熟悉使用debug()来解决函数的问题,但是如何调试othwerwise工作的函数的优化呢 Lik <- function(params, data) { .... return(-log( **likelihood equation** )) } Gene132.60705 基因1 32.31657 这不行 optim(params=c(3,10,2,9,rowMean

我有一个函数,当被要求计算-logLik给定参数时,它工作得很好。但是,如果我尝试优化函数,它会返回一条错误消息。我熟悉使用
debug()
来解决函数的问题,但是如何调试othwerwise工作的函数的优化呢

Lik <- function(params, data) { 
....
return(-log( **likelihood equation** ))
}
Gene132.60705

基因1 32.31657

这不行

optim(params=c(3,10,2,9,rowMeans(data[1,])[1]), data = data1, Lik, method = "BFGS")
optim中的错误(参数=c(3,10,2,9,rowMeans(数据[1,])[1]),数据=data1,: 无法将类型“closure”强制为类型为“double”的向量


使用内置函数名作为用户创建(或将创建)的对象名是一种不好的做法

当用户尚未创建“数据”对象(矩阵或数据帧)时,R解释器扫描环境,发现唯一名为“数据”的对象是内置的“数据”函数:

> class(data)
[1] "function"
> str(data)
function (..., list = character(), package = NULL, lib.loc = NULL, verbose = getOption("verbose"), 
    envir = .GlobalEnv)  
因此R将“数据”对象视为无法子集的闭包(函数声明):

> data[1]
Error in data[1] : object of type 'closure' is not subsettable
因此,您应该将参数的名称更改为除数据以外的其他名称

第二点,optim的语法是:

optim(par, fn, gr = NULL, ...,
           method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN",
                      "Brent"),
           lower = -Inf, upper = Inf,
           control = list(), hessian = FALSE)
因此,在您的示例中,提供给optim的第二个参数应该是函数Lik,而不是数据。解释器尝试将data1解释为闭包。您可以尝试交换data1和Lik的位置

更重要的是@李哲源Zheyunali还指出,optim中并没有名为“data”的参数。您只需将其写为“data1”来代替附加的函数参数“…”


最后,正如@Aaron指出的,第一个参数名为“par”,而不是params“

要优化的参数的
optim
参数名是
par
,而不是
params
。您不需要更改
Lik
函数,它只需要将要优化的参数作为第一个参数,名称无关紧要

这应该行得通。在这里,我也将
fn
参数命名为,但因为其他参数被命名为位置查找,所以它也行得通

optim(par=c(3, 10, 2, 9, rowMeans(data[1, ])[1]), 
      data=data1, fn=Lik, method="BFGS")
因此,代码中发生的事情是,它同时保存
params
data
以发送到函数,然后第一个未命名的参数是
Lik
,因此它与
optim
的第一个参数匹配,即
par
,即要优化的参数。该参数应为数字(从技术上讲是双精度的),但您发送给它的是一个函数(从技术上讲是闭包),因此会显示错误消息

要进行调试,您可以打开optim的调试
debug(optim)
,然后在第一次浏览时,探索它使用的参数。您会发现这一点,尽管只是在探索这些参数时,您会发现它们的命名不正确

Browse[2]> print(par)
function(params, data) {... return(-log( **likelihood equation** ))}
Browse[2]> print(fn)
Error in print(fn) : argument "fn" is missing, with no default

查看
?optim
,了解函数应该如何定义。更多选项将传递给函数,因此将数据作为参数是可以的。问题是要优化的参数的
optim
参数名是
par
,而不是
params
。您不需要更改
Lik
函数n、 它只需要将参数作为第一个参数进行优化,名称并不重要@李哲源ZheyuanLi没错,另一个问题是optim的参数顺序。data=data1和Lik放错了位置。当然,optim没有名为“data”的参数正如您也指出的。命名参数
数据
并不是代码中的问题。虽然我通常同意命名某个
数据
是个坏主意,但在函数中使用它作为参数是另一回事。这是通常做的(例如在
lm
中)并且在你想要优化的函数类型上是有意义的。
Browse[2]> print(par)
function(params, data) {... return(-log( **likelihood equation** ))}
Browse[2]> print(fn)
Error in print(fn) : argument "fn" is missing, with no default