我正在尝试优化R_j
和R_m
的似然函数,使用optim估算al_j
,au_j
,b_j
和sigma_j
。这就是我所做的。
a = read.table("D:/ff.txt",header=T)
attach(a)
a
R_j R_m
1 2e-03 0.026567295
2 3e-03 0.009798475
3 5e-02 0.008497274
4 -1e-02 0.012464578
5 -9e-04 0.002896023
6 9e-02 0.000879473
7 1e-02 0.003194435
8 6e-04 0.010281122
llik=function(R_j,R_m)
if(R_j< 0)
{
sum[log(1/(2*pi*(sigma_j^2)))-(1/(2*(sigma_j^2))*(R_j+al_j-b_j*R_m))^2]
}else if(R_j>0)
{
sum[log(1/(2*pi*(sigma_j^2)))-(1/(2*(sigma_j^2))*(R_j+au_j-b_j*R_m))^2]
}else if(R_j==0)
{
sum(log(pnorm(au_j,mean=b_j*R_m,sd=sigma_j)-pnorm(al_j,mean=b_j*R_m,sd=sigma_j)))
}
start.par=c(al_j=0,au_j=0,sigma_j=0.01,b_j=1)
out1=optim(llik,par=start.par,method="Nelder-Mead")
Error in pnorm(au_j, mean = b_j * R_m, sd = sigma_j) :
object 'au_j' not found
答案 0 :(得分:2)
让我们从错误消息开始:
Error in pnorm(au_j, mean = b_j * R_m, sd = sigma_j) :
object 'au_j' not found
所以R告诉你,当它进入pnorm
调用时,它无法在该调用中找到任何名为'au_j'的东西。您的下一步应该是查看您的函数llik
,并尝试确定您希望如何在该函数中定义变量'au_j'。
此时,答案应该相当清楚(也许!)。在llik
中没有任何地方为变量'au_j'分配了一个值。因此它不会在函数内“创建”。然后,R的范围规则将使它在全局环境中看到函数外的“au_j”。
你可能会说这是事情应该工作的地方,因为你在start.par中为'au_j'分配了一个值。但这是一个列表,R无法在列表中找到命名对象'au_j'。
所以这里的解决方案最有可能重写你的函数llik
,以便它将所有它将使用的参数作为参数,因此你将把start.par中的所有内容添加到llik的参数中。类似的东西:
llik <- function(par=c(al_j,au_j,sigma_j,b_j),R_j,R_m){...}
然后在llik中你将使用par [1]等来引用al_j。然后optim
调用应该类似于:
optim(start.par,llik,R_j=a$R_j,R_m=a$R_m)
由于您已经在a
中附加了数据,因此您可能没有在optim
调用中明确传递参数R_j和R_m,但这样做可能是一种好习惯。< / p>
我想我已经重建了你想要在这里完成的东西(以数学为模,我甚至没有看过),但我承认你的代码有点难以解析。我建议花一些时间在?optim中的示例,以确保您了解该函数的调用方式。
答案 1 :(得分:2)
很难说从哪里开始。
正如@mac所说,你的代码难以阅读。它还包含错误。
例如,如果您尝试sum[c(1,2)]
,则会收到错误:您应该使用sum(c(1,2))
。无论如何,你似乎把钱花在了错误的地方。您无法在向量上使用if
和else if
,并且需要使用ifelse
。你没有什么可以阻止标准偏差消极。还有更多。
以下代码运行时没有错误或警告。你仍然需要决定它是否符合你的要求。
a <- data.frame( R_j = c(0.002,0.003,0.05,-0.01,-0.0009,0.09,0.01,0.0006),
R_m = c(0.026567295,0.009798475,0.008497274,0.012464578,
0.002896023,0.000879473,0.003194435,0.010281122) )
llik = function(x)
{
al_j=x[1]; au_j=x[2]; sigma_j=x[3]; b_j=x[4]
sum(
ifelse(a$R_j< 0, log(1/(2*pi*(sigma_j^2)))-
(1/(2*(sigma_j^2))*(a$R_j+al_j-b_j*a$R_m))^2,
ifelse(a$R_j>0 , log(1/(2*pi*(sigma_j^2)))-
(1/(2*(sigma_j^2))*(a$R_j+au_j-b_j*a$R_m))^2,
log(pnorm(au_j,mean=b_j*a$R_m,sd=sqrt(sigma_j^2))-
pnorm(au_j,mean=b_j*a$R_m,sd=sqrt(sigma_j^2)))))
)
}
start.par = c(0, 0, 0.01, 1)
out1 = optim(llik, par=start.par, method="Nelder-Mead")