Вернуть три списка с циклом foreach в R - PullRequest
0 голосов
/ 19 октября 2018

Я боролся с работой циклов foreach в R. Чтобы ускорить мой код, я пытаюсь преобразовать свой цикл for в цикл foreach с% dopar%.

Моя цель состоит в том, чтобыв итоге получим три списка одинаковой длины, каждый из которых заполнен фреймами данных, представляющими оценки между двумя пользователями (я сравниваю три разных метода расчета).

Раньше мой код был (очень простое представление):

for (a in 1:5) {
   #Just creating some sample data    
   resultA <- data.frame(matrix(nrow = 40, ncol = 3))
   resultB <- data.frame(matrix(nrow = 40, ncol = 3))
   resultC <- data.frame(matrix(nrow = 40, ncol = 3))
   names(resultA) <- c("User1", "User2", "score")
   names(resultB) <- c("User1", "User2", "score")
   names(resultC) <- c("User1", "User2", "score")

   resultA$User1 <- 1:40
   resultB$User1 <- 1:40
   resultC$User1 <- 1:40

   resultA$User2 <- 40:1
   resultB$User2 <- 40:1
   resultC$User2 <- 40:1

   resultA$score <- sample(40)
   resultB$score <- sample(40)
   resultC$score <- sample(40)



   ListA[[a]] <- resultA
   ListB[[a]] <- resultB
   ListC[[a]] <- resultC
}

С этим кодом я действительно получаю три хороших списка, каждый из которых содержит 5 фреймов данных.

Сейчас я пытаюсь перевести это в цикл foreach, поскольку он может возвращать только одну переменную(поправьте меня если я ошибаюсь).Поэтому я решил поместить списки в основной список, но у меня возникли проблемы с получением списка из трех подсписков в результате.В основном я хочу добавить эти три списка к себе, но не друг к другу.(Поэтому добавьте resultA к ListA, resultB к ListB и т. Д.).

Я пробовал несколько вариантов .combine и .init, но, похоже, не могу понять это.С большинством функций для .combine я либо получаю огромную матрицу (что плохо, потому что я не могу различить различные методы оценки), либо списки в списках в списках в списках в ...

РЕДАКТИРОВАТЬ:Я решил свою проблему с помощью функции purrr :: transpose () для транспонирования списков в списках.Это привело к одному списку с тремя списками (именно так, как я хотел).Спасибо за помощь!

1 Ответ

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

По сути, вы можете преобразовать свой код во вложенный foreach:

library(doParallel)
registerDoParallel(cl <- makeCluster(2))
res_all <- foreach(a = 1:5) %:% foreach(b = 1:3) %dopar% {
  # Just creating some sample data    
  result <- data.frame(matrix(nrow = 40, ncol = 3))
  names(result) <- c("User1", "User2", "score")

  result$User1 <- 1:40
  result$User2 <- 40:1
  result$score <- sample(40)

  result
}
stopCluster(cl)

Вы получите список из 5 списков из 3 фреймов данных:

str(res_all)

Если вы хотите инвертироватьуровни, например, вы можете использовать {purrr}:

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