Какой лучший способ генерировать данные в R вместо цикла for?

#r #for-loop #simulation #parallel.foreach

#r #цикл for #Симуляция #parallel.foreach

Вопрос:

Я совершенно новый пользователь R, пытающийся сгенерировать большой объем данных с указанными зависимыми ассоциациями в одном data.frame.

Мой текущий код использует цикл for и работает нормально (N = 250 идентификаторов, более 10 репликаций), но мне придется расширить его до большего числа N и более K репликаций. Я пробовал параллельную обработку с использованием foreach и функций без особого успеха. Я не могу получить реплицированные данные для добавления в конечный кадр.

Любая помощь или направление будут высоко оценены.

Текущий код:

 set.seed(0)

Kreps <- 10  

id= as.numeric(1:250)

sim=do.call("rbind", replicate(Kreps,data.frame(id), simplify=FALSE))

sim$Krep_num = as.numeric(gl(Kreps,250))
obs1<-nrow(sim)

for(m in 1:Kreps  ){ 
  sim$z1= rbinom(obs1, 1, 0.35)

  sim$x1= rbinom(obs1, 1,exp(log(0.10)  (log(1.15)*sim$z1)))
                   
  sim$y=  rbinom(obs1, 1,exp(log(0.025) (log(2)*sim$x1)   (log(1.2)*sim$z1)) )
}
  

Ответ №1:

Главное в ускорении моделирования в R похоже на векторизацию любого фрагмента кода в R. В основном, когда это возможно, используйте внутренние функции, а не for-loops . Иногда может быть получено математическое соотношение, и несколько вызовов могут быть удалены из канала. В этом случае простое удаление цикла for и выполнение всех симуляций за 3 вызова rbinom значительно ускорит его.

 set.seed(0)
Kreps <- 10  
id = 1:250
obs1 <- Kreps * length(id)
nsim <- obs1 * Kreps
df <- data.frame(id = rep(id, kreps))
df$z1 <- rbinom(nsim, 1, 0.35)
df$x1 <- rbinom(nsim, 1, exp(log(.1)   log(1.15) * df$z1))
df$y <- rbinom(nsim, 1, exp(log(.025)   log(2) * df$z1  log(1.2) * df$x1))
  

Также, когда вы хотите реплицировать свои данные, rep это будет намного быстрее, чем replicate . rep просто копирует ваш набор данных, в то время как replicate реплицирует вызов, который вы размещаете. Например. rep(rbinom(1e6), 10) (примерно) эквивалентно x <- rbinom(1e6); unlist(lapply(1:6, function(z)x)) , в то время как replicate(10, rbinom(1e6)) примерно эквивалентно lapply(1:6, function(x)rbinom(1e6)) .