Как оптимизировать 2 цикла - PullRequest
       4

Как оптимизировать 2 цикла

1 голос
/ 13 декабря 2011

Я запускаю симуляцию, пытаясь найти вероятность того, что что-то произойдет в ряде биномиальных испытаний. Я начинаю с указанием данных

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 содержит результаты двух биномиальных испытаний и так далее. Если биномиальное событие происходит в любом из one, two, three, ..., 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 Ответ

4 голосов
/ 13 декабря 2011
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)
}

Для iter из 16000 это работает за 2,29 с на моей машине, по сравнению с (приблизительно) 1781 с для упорядочения в вашем исходном алгоритме. В общем случае не назначайте отдельные элементы во фрейме данных, если вы можете назначить сразу весь столбец. Возможны и другие улучшения, но я остановлюсь на ускорении> 750x (и изменим алгоритм с времени выполнения O (n ^ 2) на O (n)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...