当函数随着每次迭代而增加时,如何编写for循环?

时间:2013-11-21 23:24:32

标签: r for-loop winbugs jags

我试图估计在移除动物并检测时间和空间变化的多个观察期内从n.sites中检测动物的概率。如果我在5个观察期内做这样的事情,它就有效:

for(i in 1:nsites){
  mu[i,1] <- p[i,1]
  mu[i,2] <- p[i,2]*(1-p[i,1])
  mu[i,3] <- p[i,3]*(1-p[i,1])*(1-p[i,2])
  mu[i,4] <- p[i,4]*(1-p[i,1])*(1-p[i,2])*(1-p[i,3])
  mu[i,5] <- p[i,5]*(1-p[i,1])*(1-p[i,2])*(1-p[i,3])*(1-p[i,4])
}

时间2的概率取决于时间1的概率,时间3的概率取决于时间1和2的概率。如果我只是这样做了5个时间段,它就不会写出这个很重要。但是当我得到10个,15个,20个以上的时间段时,写出来就很麻烦了。我觉得应该有一种方法来编写这个循环而不用键入每一步,但我只是想不出怎么做。可能是额外的索引或其他控制语句或幂函数。如果p [i]在每个第j个观察中相同(即p [i,1] = p [i,2] = p [i,3]等),那么它将是:

p[i]*(1-p[i])^5

任何建议都将不胜感激。

这是BUGS语言代码。我在R工作,并通过rjags包将代码发送到JAGS。 BUGS,R或伪代码适合我的目的。

以下是可以模拟问题的R代码:

set.seed(123)
testp <- matrix(runif(108, 0.1, 0.5), 108, 5)
testmu <- matrix(NA, 108, 5)

for(i in 1:nsites){
  testmu[i,1] <- testp[i,1]
  testmu[i,2] <- testp[i,2]*(1-testp[i,1])
  testmu[i,3] <- testp[i,3]*(1-testp[i,1])*(1-testp[i,2])
  testmu[i,4] <- testp[i,4]*(1-testp[i,1])*(1-testp[i,2])*(1-testp[i,3])
  testmu[i,5] <- testp[i,5]*(1-testp[i,1])*(1-testp[i,2])*(1-testp[i,3])*(1-testp[i,4])
}

感谢您的帮助。 丹

3 个答案:

答案 0 :(得分:4)

这确实看起来像一个非常适合R Reduce的任务:

testmu3 <- matrix(NA, 108, 5)
nsites = 108
np = 5

for (i in 1:nsites) {
   testmu3[ i, ] <- Reduce( function(x,y) x*(1-y), testp[i, ], 
                                                   accumulate=TRUE)
}
max(abs(testmu3-testmu))
[1] 0

accumulate参数创建了一个不断增长的中间结果向量。

> testp[1, ]
[1] 0.215031 0.215031 0.215031 0.215031 0.215031

> Reduce( function(x,y) x*(1-y), testp[1, ],  accumulate=TRUE)
[1] 0.21503101 0.16879267 0.13249701 0.10400605 0.08164152

答案 1 :(得分:3)

@ Frank的答案更清晰(可能更快),但这也会有效,可能会更容易理解。

testmu2 <- matrix(NA, 108, 5)
nsites = 108
np = 5

for (i in 1:nsites) {
  fac <- 1
  testmu2[i,1] <- testp[i,1]
  for (j in 2:np) {
    fac <- fac * (1-testp[i,j-1])
    testmu2[i,j] <- testp[i,j] * fac
  }
}
max(abs(testmu2-testmu))
[1] 2.775558e-17

答案 2 :(得分:2)

这是一种方式:

testmu2 <- testp*t(apply(cbind(1,1-testp[,-5]),1,cumprod))

在我的电脑上,它们几乎匹配:

> max(abs(testmu2-testmu))
[1] 2.775558e-17

我不知道BUGS / JAGS,但我们的想法是首先在其列中获取1-p矩阵的累积乘积,然后取p *结果。