使用R

时间:2018-10-19 14:24:16

标签: r list foreach

我一直在为R中的foreach循环而苦苦挣扎。 为了加快我的代码的速度,我尝试使用%dopar%将for循环更改为foreach循环。

我的目标是最终得到三个相同长度的列表,每个列表填充有表示两个用户之间得分的数据框(我正在比较三种不同的计算方法)。

我的代码曾经是(非常基本的表示形式):

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 :(得分:1)

基本上,您可以将代码转换为嵌套的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)

您将获得包含3个数据帧的5个列表的列表:

str(res_all)

如果要反转电平,可以例如使用{purrr}:

str(purrr::transpose(res_all))