【发布时间】:2016-08-05 12:29:04
【问题描述】:
我在 R 中编写了以下函数。我想迭代它,比如 50000 次。我在我的函数中使用了“sapply”,但它在 R 中运行缓慢。我的电脑现在仍在工作大约 20 小时,我不知道运行时间。任何想法如何加快此操作?谢谢。
data=matrix(c(0.01132162,1,0.04056053,1,0.11676735,0,0.12029087,1,
0.16197702,1,0.17190980,1,0.20386841,1,0.21251687,0,
0.36536492,0,0.40256414,1),ncol=2,byrow=T)
GIBS=function(data,a,b,beta,R)
{
m=length(R)
n1=sum(data[,2]==1)
n2=m-n1
n=m+sum(R)
N=c(n1,n2)
R1=c(0,R)
nstar=c()
for(i in 1:m) nstar[i]=n-(i-1)-sum(R1[1:i])
Z=c(data[1,1],data[2:m,1]-data[1:(m-1),1])
f=function(x)
{
A=0
for(i in 1:m) A=A+x^i*nstar[i]*Z[i]
FR=1
for(j in 1:2) FR=FR*(A+b[j])^(N[j]+a[j])
return(x^(m*(m+1)/2)*exp(-beta*(x-1))/FR)
}
INT=integrate(f,1,Inf)$value
SG=function(it)
{
uu=runif(1)
g0=function(t) integrate(f,1,t)$value/INT-uu
aa=5
if(g0(1)>0) {while(g0(aa)>0) aa=aa+1} else {while(g0(aa)<0) aa=aa+1}
ra=uniroot(g0,c(1,aa))$root
A1=sum(ra^(1:m)*nstar*Z)
rl1=rgamma(1,n1+a[1],A1+b[1])
rl2=rgamma(1,n2+a[2],A1+b[2])
return(c(ra,rl1,rl2))
}
return(colMeans(t(sapply(1:10000,SG,simplify = "array"))))
}
########
BGI=matrix(NA,ncol=3,nrow=50000)
for(iter in 1:50000)
{
BGI[iter,]=GIBS(data,c(2,1.6),c(2,2),5,c(10,rep(0,9)))
cat(iter, "of 50000\r")
flush.console()
}
【问题讨论】:
-
未完成的原因是代码中存在错误。在许多情况下,对象长度不一致。由于该函数被命名为
GIBS,请问这是否应该是一个 Gibbs 采样器?如果是这样,您可能会找到一个预先存在的包/功能来满足您的需求。 -
谢谢,我的功能不完全是 Gibbs 采样器。
-
如果你在你的 for 循环中放了一个
print(iter),那么你就会知道它有多远,并且通过扩展可以猜测它需要多长时间。至于问题本身,R 的循环速度不是很快,在sapply、while和for循环之间,您的代码中有很多内容。最好的选择是使用 Rcpp,假设这足以证明这项工作的合理性,但不幸的是,这将需要您在 cpp 中重写大部分代码。 -
@K.Ahmadi:关于速度this 或许有帮助