【发布时间】:2019-04-12 09:04:58
【问题描述】:
(没有用于 r-parallel-processing 或 R 的 foreach 包的标签,如果有的话我会在这里标记它们。欢迎标记建议)。
我有一个数据框“training_data”和一个向量“cats”(用于分类数据)。
猫看起来像c("fruits", "vegetables", "meats")
我想遍历训练数据中的每只猫,并用“其他”替换任何低频级别。
这行得通:
library(foreach)
foreach(c = cats) %do% { # not parallel processing
print(c)
freqs <- table(training_data[c])
low_freqs <- names(which(freqs < 20000))
training_data[c][[1]] <- ifelse(training_data[c][[1]] %in% low_freqs, "Other", training_data[c][[1]])
return(NULL) # otherwise spits out the whole thing
}
在每次迭代中,第一行 print(c) 输出正在操作的向量猫的值,我在控制台中看到它:
“水果” “蔬菜” “肉”
在这些猫之后,3 个 NULL 实例被打印到终端,这是由于循环中的最后一行而预期的。然后,当我检查我的数据框 training_data 时,分类变量已按预期进行转换。任何频率低于 20k 的级别都已替换为其他级别。
但是,如果我尝试使用并行:
library(foreach)
foreach(c = cats) %dopar% { # parallel (I have 8 cores)
print(c)
freqs <- table(training_data[c])
low_freqs <- names(which(freqs < 20000))
training_data[c][[1]] <- ifelse(training_data[c][[1]] %in% low_freqs, "Other", training_data[c][[1]])
#return(NULL) # otherwise spits out the whole thing
}
所有发生的事情就是将 NULLS 打印到控制台。训练数据未转换,控制台中未显示 print(c)。
为什么只有 %do% 有效,而 %dopar% 无效?
【问题讨论】:
-
使用 %dopar% 对 training_data 的分配发生在每个创建的子进程中,该子进程不共享公共环境,因此丢弃更改。使用 %do% 变量位于当前环境中,因此修改后的值仍然存在。
-
啊。我认为这是有道理的。感谢您的澄清。
标签: r doparallel