Вопрос очень неясен, но из вашего вопроса кажется, что вы пытаетесь объединить выходы в одну среду, чтобы получить большую скорость.
Теперь вы, вероятно, должны отметить несколько вещей.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
для экспорта вывода в определенную среду.
Примечание использование tickerIter
вместо необработанных тикеров.
output <- foreach(r = tickerIter,
.combine = function(...){
c(...) #Combine all outputs into a list
},
.multicombine = TRUE,
.packages = "quantmod")%dopar% {
currenv <- environment()
getSymbols(r, currenv)
as.list(currenv)
}
#If you really want it in a specific environment, you could use: (Could also be used in .combine)
list2env(output, hub)