Использование вложенной l oop в R альтернативе - PullRequest
0 голосов
/ 21 января 2020

У меня есть следующий код, который я пытаюсь ускорить в R, поскольку я знаю, что циклы медленнее в R. Есть ли способ сделать это в R без необходимости использовать вложенные циклы.

# initialize 2 vectors of length 10,000
totalNum <- rep(0,10000)
totalAmt <- rep(0,10000) 
values <- sample(200:5000,150000, replace = TRUE)
chances <-  # similar to f in length and contains values between 0 and 1 

# loop over length of a vector 
 for (i in 1:150000){
   # value between 200-5000 
   value <- values[i]
   # value of number between 0 and 1 
   chance <- chances[i]

  # loop over vectors created 
  for (j in 1:10000){
    # run test 
    dice <- runif(1)
    if (dice < chance){

    totalnum[j] <-  totalNum[j] + 1
    totalAmt[j] <- totalAmt[j] + value
   }

  }

}

Я пытался использовать lapply или mapply, но не похоже, что это подойдет для этой ситуации.

Ответы [ 2 ]

2 голосов
/ 21 января 2020

size = 150000 для векторов значений и шансов

library('data.table')
df1 <- data.table(totalNum = rep(0,10000),
                  totalAmt = rep(0,10000))
values <- sample(200:5000,150000, replace = TRUE)
chances <-  runif(n=150000, min=1e-12, max=.9999999999)

invisible( mapply( function(value, chance){
  df1[runif(10000) < chance, `:=` (totalNum = totalNum + 1, totalAmt = totalAmt + value)]
  return(0)
}, value = values, chance = chances) )

В моей системе этот код завершается в следующий раз с использованием функции system.time().

# user  system elapsed 
# 252.83   43.93  298.68 
1 голос
/ 21 января 2020

lapply и mapply - это просто скрытые циклы с незначительным улучшением по сравнению с for l oop. Для значительного улучшения вам необходимо использовать векторизованные формы функций.

Внутренний l oop легко заменяется векторизованной формой:

#generate all of the rolls
dice<-runif(10000)

#identify the affected index
dicelesschance<-which(dice<chance)

#update the values 
totalNum[dicelesschance]<-totalNum[dicelesschance] + 1
totalAmt[dicelesschance]<-totalAmt[dicelesschance] + value

Это должно иметь заметное улучшение производительность.

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