如何优化2个循环

时间:2011-12-12 22:01:02

标签: r

我正在进行模拟试图找出在一些二项式试验中发生某事的可能性。我从指定数据开始

iter=5000
data=data.frame(prob=runif(300), value=runif(300))
data<-data[sample(nrow(data), iter, replace=T),]

然后我添加试验

cols <- c("one","two","three","four","five","six",
          "seven","eight","nine","ten","eleven","twelve")
data[,cols] <- NA

one仅包含一项二项式试验的结果,two包含两项二项式试验的结果,依此类推。如果在onetwothree,...,twelve中的任何一个中发生二项式事件,则该单元格标记为1,否则为0.

然后我运行iter=5000模拟的试验

for (col in 3:14) {
  for (i in 1:iter) if (sum(rbinom((col-2),1,data[i,1]))>0) data[i,col]<-1 else data[i,col]<-0
}

然后我评估mean(data$value[data$one==0]直到... mean(data$value[data$twelve==0]

我的问题是模拟代码永远需要iter>15000

  for (col in 3:14) {
    for (i in 1:iter)
      data[i,col] <- if (sum(rbinom((col-2),1,data[i,1]))>0) 1 else 0
  }

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

sim2 <- function(iter) {
    dat <- data.frame(prob=runif(300), value=runif(300))
    dat <- dat[sample(nrow(dat), iter, replace=TRUE),]
    cols <- c("one","two","three","four","five","six",
              "seven","eight","nine","ten","eleven","twelve")
    dat[,cols] <- 0

    for (col in 3:14) {
        dat[,col] <- as.numeric(vapply(dat[,1],
                                       function(p) {sum(rbinom((col-2), 1, p))>0},
                                       FUN.VALUE = TRUE))
    }
    vapply(3:14, function(col) {mean(dat$value[dat[,col]==0])}, FUN.VALUE=1)
}

对于16000的iter,这在我的机器上以2.29s运行,而原始算法中的排序为(估计的)1781s。通常,当您可以一次分配整个列时,不要在数据框中分配单个元素。可能会有更多改进,但我将停止在> 750x加速(并将算法从O(n ^ 2)的运行时间更改为O(n))。