在 R 中运行 foreach 而不返回任何值
Posted
技术标签:
【中文标题】在 R 中运行 foreach 而不返回任何值【英文标题】:Running foreach without returning any value in R 【发布时间】:2020-05-21 03:30:17 【问题描述】:我有一个函数 doSomething(),它在 foreach 循环中运行,因此将一些计算保存为 .csv 文件。因此,我不需要 foreach 的返回值,实际上我不想要返回值,因为它使我的记忆变得混乱,以至于我无法运行尽可能多的迭代。
如何强制 foreach 没有返回值,或删除迭代的返回值?
这是一个说明我的问题的最小示例:
cl <- parallel::makePSOCKcluster(1)
doParallel::registerDoParallel(cl)
"%dopar%" <- foreach::"%dopar%"
doSomething <- function ()
a <- as.numeric(1L)
foreach::foreach (i = 1:4) %dopar%
doSomething()
输出是:
[[1]]
[1] 1
[[2]]
[1] 1
[[3]]
[1] 1
[[4]]
[1] 1
【问题讨论】:
doSomething(); NULL
是什么?
这将返回一个 NULL 列表
我觉得你的问题不是退货,是内存给你带来困扰吧?
谢谢你的建议,我会试试这个。但是,我发现使用的内存随着时间的推移呈线性增长,这让我相信 foreach 创建的巨大列表作为返回值是问题所在。
@Freakazoid 确实在每个工人中使用 rm() 和 gc() 产生了预期的结果!感谢您的帮助,如果您想添加自己的答案,我会接受。
【参考方案1】:
正如达里奥所说; foreach
返回一个列表。因此,您要做的是改用for
循环。您可以在循环中使用write.csv
函数将每次迭代的结果写入csv文件中。
对于并行计算,请尝试使用 parallel
包中的 parSapply
函数:
library(parallel)
cl <- parallel::makePSOCKcluster(1)
doParallel::registerDoParallel(cl)
parSapply(cl, 1:4, function(doSomething) a <- as.numeric(1L))
编辑;
结合 Freakozoid 的建议(将 rm 函数的参数设置为a
);
library(parallel)
cl <- parallel::makePSOCKcluster(1)
doParallel::registerDoParallel(cl)
parSapply(cl, 1:4, function(doSomething) a <- as.numeric(1L); write.csv(a, "output.csv"); rm())
将为您提供 csv 文件的结果输出,以及NA
s 的列表。由于该列表仅包含 NA
s,因此可能不会占用太多空间。
请告诉我结果。
【讨论】:
【参考方案2】:R 中的并行计算(就我的经验而言)这样可以为每个集群节点分配内存。
这意味着如果您有一个每个节点都需要计算的大数据集,那么这些数据将被多次分配。这会导致高 RAM 消耗。由于您想在每个循环中写入输出并在之后丢弃结果,您可以尝试 rm
函数并在每个函数调用中调用垃圾收集(例如使用 gc
)。
如上所述,这适用于E L M。感谢测试!
【讨论】:
【参考方案3】:来自?foreach
:
foreach 和 %do%/%dopar% 运算符提供循环结构 可以看作是标准 for loop 和 lapply 的混合体 功能。它看起来类似于 for 循环,它计算一个 表达式,而不是函数(如 lapply),但它的目的是 返回一个值(默认为列表),而不是导致 副作用。
线
但它的目的是返回一个值(默认为列表)
表示这是 foreach 的预期行为。不知道你想如何从那开始......
【讨论】:
也许有一种方法可以丢弃迭代的返回值并让 foreach 最后返回一个空列表?或者你能在我的情况下想出一个替代方案,也许使用不同的并行化工具?以上是关于在 R 中运行 foreach 而不返回任何值的主要内容,如果未能解决你的问题,请参考以下文章
PHP - 提交日期/时间/从foreach循环中选择输入值到$ _POST不返回任何内容
如何在行和返回值中匹配一个变量而不是在r代码中返回另一行的另一个条件