如何让R语言中简单的dopar示例正常运行(结果返回NA问题)
问题分析与解决
你的代码运行后结果全为NA,核心原因有两个:
- 并行子进程无法访问
data_list:makeCluster创建的子进程默认不会自动加载主环境变量,子进程找不到data_list,计算自然返回NA。 - 结果维度不匹配:你用
.combine=rbind,每个foreach循环会返回3行的矩阵,但要赋值给r[i,](长度为3的向量),维度不匹配导致赋值失败,最终数组被NA填充。 - 列表元素取值错误:
data_list[[i]][j]返回的是长度为1的列表,而非向量,mean无法正确计算列表的均值。
修正后的代码
library(doParallel) library(parallel) library(foreach) # 构造数据 data1.1 = 1:9 # mean(data1.1) = 5 data1.2 = 2:10 # mean(data1.2) = 6 data1.3 = 3:11 # mean(data1.3) = 7 data2.1 = 4:12 # mean(data2.1) = 8 data2.2 = 5:13 # mean(data2.2) = 9 data2.3 = 6:14 # mean(data2.3) = 10 data3.1 = 7:15 # mean(data3.1) = 11 data3.2 = 8:16 # mean(data3.2) = 12 data3.3 = 9:17 # mean(data3.3) = 13 data_list = list("1" = list("1" = data1.1, "2" = data1.2, "3" = data1.3), "2" = list("1" = data2.1, "2" = data2.2, "3" = data2.3), "3" = list("1" = data3.1, "2" = data3.2, "3" = data3.3)) # 创建集群并导出变量 cl = parallel::makeCluster(detectCores() - 2, output = "") # 将data_list导出到所有子进程 parallel::clusterExport(cl, "data_list") doParallel::registerDoParallel(cl) r = array(0, c(3, 3)) for (i in 1:3) { r[i, ] = foreach::foreach(j = 1:length(data_list[[i]]), .combine = c) %dopar% { # 用双层[[取出向量元素 mean(data_list[[i]][[j]]) } } # 停止集群释放资源 parallel::stopCluster(cl) # 查看结果 print(r)
关键修改说明
- 新增
clusterExport(cl, "data_list"):把主环境的data_list导出到所有子进程,确保子进程能访问到计算所需的数据。 - 将
.combine=rbind改为.combine=c:让foreach返回长度为3的向量,与r[i,]的维度匹配,避免赋值失败。 - 修正取值方式:将
data_list[[i]][j]改为data_list[[i]][[j]],取出列表中的向量元素,确保mean能正确计算均值。
运行修正后的代码,即可得到期望结果:
[,1] [,2] [,3] [1,] 5 6 7 [2,] 8 9 10 [3,] 11 12 13
内容的提问来源于stack exchange,提问作者Michael Szczepaniak
相关产品推荐
相关产品推荐

