我正在尝试编写由集成定义的分布的似然函数。我正在使用integrate()函数,但当我尝试在函数的其余部分使用它时,我得到错误:
“B中的错误(alpha + i,beta + 6 - i)/ B(alpha,beta):二元运算符的非数字参数”
积分的值例如是“9.501501,绝对误差<0.00078”。我试过使用trunc(),但这也无济于事。我对R比较陌生,所以有一个已知的解决方案吗?任何帮助将不胜感激!
B <- function(a,b){
integrand <- function(t){(t^(a-1))*((1-t)^(b-1))}
integrate(integrand,lower=0,upper=1)
}
betalik <- function(alpha,beta){
likelihood <- 0 Z <- c(37,22,25,29,34,49)
for(i in 1:6)
likelihood <- likelihood +
Z[i]*log((B(alpha+i,beta+6-i))/B(alpha,beta))
return(likelihood)
}
道连,
答案 0 :(得分:4)
使用?integrate
....
integrate(dnorm, -1.96, 1.96)
# 0.9500042 with absolute error < 1e-11
这里到底发生了什么?那么,集成函数创建一个“集成”类S3对象,它基本上是一个包含许多字段的列表,然后将print()
应用于它,依次执行print.integrate()
。该函数的输出实际上字符串“0.9500042,绝对错误<1e-11”,它只是以这种方式显示。
要了解integrate()
实际创建的R对象,请执行
obj = integrate(dnorm, -1.96, 1.96)
str(obj)
# List of 5
# $ value : num 0.95
# $ abs.error : num 1.05e-11
# $ subdivisions: int 1
# $ message : chr "OK"
# $ call : language integrate(f = dnorm, lower = -1.96, upper = 1.96)
# - attr(*, "class")= chr "integrate"
因此,如果您只想要积分值,那么您必须提取该函数创建的列表的value
字段,以便进行计算。 E.g。
10*integrate(dnorm, -1.96, 1.96)$value
# [1] 9.500042
答案 1 :(得分:4)
跟进上面的评论和答案......
以下是您的原始函数,格式更精确,整合@Fhnuzoag关于从$value
结果中提取integrate()
组件的注释:
B <- function(a,b){
integrand <- function(t){(t^(a-1))*((1-t)^(b-1))}
integrate(integrand,lower=0,upper=1)$value
}
betalik <- function(alpha,beta){
likelihood <- 0
Z <- c(37,22,25,29,34,49)
for(i in 1:6) likelihood <- likelihood +
Z[i]*log((B(alpha+i,beta+6-i))/B(alpha,beta))
return(likelihood)
}
在这里,我们检查@dason的评论,即你的B
函数等同于R的内置beta
函数(但R函数当然更快,可能更准确):
all.equal(B(1.1,2.7),beta(1.1,2.7)) ## TRUE
我更喜欢分别指定'数据':
Z <- c(37,22,25,29,34,49)
使用内置lbeta
(log-beta)函数的似然函数的新版本,并进行了矢量化:
blik2 <- function(alpha,beta,Z) {
index <- 1:6
sum(Z*(lbeta(alpha+index,beta+6-index)-lbeta(alpha,beta)))
}
all.equal(blik2(1.1,2.7,Z),betalik(1.1,2.7))
## small difference, blik2 is *probably* more
## accurate ... "Mean relative difference: 6.406495e-08"
(最好进一步概括这一点并将代码中的6
值替换为length(Z)
...)