Выборочная итерация без цикла for в R - PullRequest
0 голосов
/ 12 октября 2018

Несмотря на то, что я думаю, что проблема у меня может быть простой, я, тем не менее, не могу понять это.Вот в чем дело:

У меня есть следующий список и вектор.Список используется для заполнения вектора:

probabilities = list(c(0.2, 0.3, 0.5), c(0.1, 0.1, 0.8), c(0.3,0.4,0.3))
nextState = c()

for(counter in 1:3){
nextState[counter] = sample(1:3, size = 1, prob = probabilities[[counter]])
}

Код работает нормально.Однако при расширении до более крупных списков (> 10 000 элементов) цикл становится все более медленным.Поскольку вышеприведенный цикл многократно используется в большем коде, затрачиваемое время слишком много.Был бы способ достичь того же результата без зацикливания?

Дополнительный вопрос:

Спасибо, ребята, вы мне очень помогли.Еще один вопрос: как бы подойти к той же проблеме, если вероятности и следующее состояние являются взаимозависимыми значениями, как я могу избежать цикла for?Возможно, какой-то код для уточнения:

M <- list(matrix(c(0.1, 0.2, 0.7, 0.2, 0.2, 0.6, 0.3, 0.3, 0.4), nrow = 3, ncol = 3), 
         matrix(c(0.3, 0.3, 0.4, 0.5, 0.5, 0, 0.1, 0.1, 0.8), nrow = 3, ncol = 3))

probabilities <- list()
nextState <- c(2, NA, NA)

for(i in 1:2){
probabilities[[i]] <- M[[i]][nextState[i], ]
nextState[i + 1] <- sample(1:3, size = 1, prob = probabilities[[i]])
}

Если у вас есть идеи, то вы действительно чудотворцы !!

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Другая возможность с пакетом purrr:

library(purrr)

nexstate <- map_int(probabilities, function(x) {sample(1:3, size = 1, prob = x)})

Данные:

probabilities = list(c(0.2, 0.3, 0.5), c(0.1, 0.1, 0.8), c(0.3,0.4,0.3))
0 голосов
/ 12 октября 2018

попробовать sapply

nextstate <- sapply( probabilities, function(x) {sample(1:3, size = 1, prob = x)})

тесты

# Unit: microseconds
#   expr      min       lq      mean    median       uq      max neval
#    for 2115.170 2223.475 2436.0797 2283.2755 2371.546 10048.64   100
# sapply   24.704   29.524  164.0261   37.3565   41.123 12763.03   100


microbenchmark::microbenchmark(
  `for` = { 
    nextState = c()
    for(counter in 1:3){
      nextState[counter] = sample(1:3, size = 1, prob = probabilities[[counter]])
    }
  },
  sapply = sapply( probabilities, function(x) {sample(1:3, size = 1, prob = x)}),
  times = 100)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...