将并行Foreach调用导出到环境中

问题描述 投票:0回答:1

我想将foreach中的输出输出到环境中。我正在从雅虎财经中提取时间序列数据。

library(quantmod)
library(foreach)
library(parallel)
library(doParallel)
registerDoParallel(cores=2)

hub = new.env()
tickers = c("NKE", "AAPL", "MSFT", "TSLA", "MPC", "PEP", "GIS", "MA","V", "CAT", "KHC", "AMZN", "NFLX", "GS", "MS", "BAC", "GE", "KO", "JPM", "AMAT", "ABT", "BIIB")

#I have tried 2 methods below.
#The first gives me a list of just the ticker names.
#The second puts the data into a list. I am looking for an enviornment
foreach(r = tickers, .packages = "quantmod") %dopar% lapply(r, getSymbols, env = hub)

enviro = foreach(r = tickers, .packages = "quantmod")%dopar% lapply(r, getSymbols, auto.assign = F)

class(enviro)
[1] "list"

环境应该看起来像这样(当我不在foreach循环中运行它时它会起作用)。

hub = new.env()
#the following line of code takes about 1 min. Just a heads up
getSymbols(tickers, env = hub)
r foreach quantmod parallel.foreach doparallel
1个回答
1
投票

这个问题非常不清楚,但从您的问题来看,您似乎正在尝试将输出组合到一个单一的环境中,以获得更快的速度。

现在你应该注意一些事情。 quantmod::getSymbols每次通话都有一些开销。使用当前方法,由于为每个符号调用函数,您应该会看到性能损失。

优化

减少开销的一种方法是将每个计算拆分成块。 foreach包依赖于iterators包,它允许人们将计算分成块,非常简单。

nworker = 2
registerDoParallel(cores = nworker)
tickers = matrix(c("NKE", "AAPL", "MSFT", "TSLA", "MPC", "PEP", "GIS", "MA","V", "CAT", "KHC", "AMZN", "NFLX", "GS", "MS", "BAC", "GE", "KO", "JPM", "AMAT", "ABT", "BIIB"), ncol = 1)
tickerIter <- iterators::iter(tickers, by = 'row', #I made a 1 column matrix, so i will iterate over each row.
                              chunksize = ceiling(length(tickers)/nworker) #Set chunk size, such that each worker gets 1 job.
)

在上面的代码中,tickerIter现在是所有符号的迭代器,块长度为nworker。因此,每个工作者(核心)只获得一个块,我们只需要导出到每个工作者一次并从中导入。 tickerIter将作为我们在foreach循环中的参数而不是原始代码。要查看迭代器如何输出到foreach循环,您可以尝试执行nextElem(tickerIter),它将输出一个块。但是请注意,您需要重新分配迭代器,因为如果已经使用foreach输出,则不会在nextElem循环中分配块。

融入环境

从您想要将输出组合到单个环境中的问题。直接在foreach中执行此操作根本不可能,至少不会没有崩溃R会话的危险。默认情况下,Foreach通过创建多个R会话,导出数据和执行提供的代码/表达式来执行并行化。因此,您必须挂钩到当前的R会话,并通过此挂钩将变量分配给环境。不建议这样做。

但是foreach包含一个.combine参数,可以给出一个自定义函数来组合。此外,如果该功能可以组合任意数量的输入,则使用.multicombine = TRUE时,该功能仅对每个输出执行一次。

我不明白你为什么要将它们专门添加到集线器环境中,因为在下面的代码示例中,输出被组合成一个列表。然后可以使用list2env转换列表以将输出导出到特定环境中。

注意使用qazxsw poi而不是原始票。

tickerIter
© www.soinside.com 2019 - 2024. All rights reserved.