我一直在为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()函数将列表中的列表转置来解决了我的问题。这样就产生了一个包含三个列表的列表(正是我想要的方式)。感谢您的帮助!
答案 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))