R - параллельная обработка и ошибка ldply

Я пытаюсь использовать приведенный ниже код для выполнения вызовов API в параллельном процессе, чтобы ускорить вызовы API. (Я знаю, что это не лучший способ ускорить вызовы API, но он работает)

Это терпит неудачу только тогда, когда я пытаюсь использовать параллель, в противном случае он работает. В функции ldply я получаю следующую ошибку:

Ошибка в do.ply (i): не удалось выполнить задачу 1 - «объект типа 'closure' не является подмножеством». Кроме того:

Предупреждающие сообщения:

1:: ... может использоваться в неправильном контексте: ‘.fun (piece, ...)’

2:: ... может использоваться в неправильном контексте: ‘.fun (piece, ...)’

любая помощь будет оценена по достоинству!

One <- 26    

cl<-makeCluster(4) 
registerDoSNOW(cl)

func.time <- Sys.time()

## API CALL ONE FOR "kline" 
url <- "https://api.binance.com"
path <- paste("/api/v1/klines?symbol=",pairs[1],"&interval=1m&limit=1", sep = "")

raw.results <- GET(url = url, path = path)

text_content <- content(raw.results, as = "text", encoding = "UTF-8")


kline <- data.frame(text_content %>% fromJSON())
kline$symbol <- pairs[1]



## API FUNCTION TO BE APPLIED FOR REST
loopfunction <- function(i){
  url <- "https://api.binance.com"
  path <- paste("/api/v1/klines?symbol=",pairs[i],"&interval=1m&limit=1", sep = "")

  raw.results <- GET(url = url, path = path)

  text_content <- content(raw.results, as = "text", encoding = "UTF-8")

  kline_temp <- data.frame(text_content %>% fromJSON())
  kline_temp$symbol <- pairs[i]
  kline <- rbind(kline,kline_temp)

  return(kline)
}

## DPLY PARALLEL FUNCTION
kline2 <- data.frame(ldply(2:(One - 1), .fun =  loopfunction, .parallel = T, .paropts = c("httr", "jsonlite", "dplyr"))) ##"ONE" is a list varriable created earlier
stopCluster(cl)


func.end.time <- Sys.time()

func.tot.time ‹- func.end.time - func.time


person Federico Marchese    schedule 31.01.2018    source источник


Ответы (1)


Ваш вопрос нельзя полностью воспроизвести, поэтому следующее предположение является обоснованным.

Ваш loopfunction() ссылается на объект с именем pairs. Из вашего скрипта кажется, что переменная с именем pairs определена где-то в вашей локальной среде. Однако, когда loopfunction() передается в ldply(), у него больше нет доступа к этой переменной (обычно так и было бы, но для распараллеливания требуется создание новых сред R). Не сумев найти в среде объект с именем pairs, R продолжает поиск и находит совпадение в stats::pairs(). Это функция построения графика, а не подмножественный объект, такой как вектор или фрейм данных. Следовательно, сообщение об ошибке «объект типа« закрытие »не является подмножеством».

Я не особо знаком с тем, как ldply реализует параллельную обработку, но вы, вероятно, могли бы изменить определение своей функции следующим образом:

loopfunction <- function(i, pairs) {
   ...[body of function]...
}

И передайте pairs в качестве дополнительного параметра в вашем ldply вызове:

kline2 <- data.frame(ldply(2:(One - 1), .fun =  loopfunction, pairs = pairs, .parallel = T, .paropts = list(.packages = c("httr", "jsonlite", "dplyr"))))
person jdobres    schedule 31.01.2018
comment
звучит так, как будто это могло быть так. Я не прикреплял весь код, потому что он очень длинный, но объект пар создается раньше в коде. Как передать его на параллельный запуск? - person Federico Marchese; 31.01.2018
comment
Отредактировал свой ответ, чтобы предложить, как это сделать - person jdobres; 31.01.2018
comment
Шаг в правильном направлении, но почему-то теперь я получаю: задача 1 не удалась - не удалось найти функцию GET. Я думаю .paropts = c (httr, jsonlite, dplyr) на самом деле не импортирует библиотеку httr - person Federico Marchese; 31.01.2018
comment
Я думаю, ты действительно хочешь .paropts = list(.packages = c("httr", "jsonlite", "dplyr")). - person jdobres; 31.01.2018
comment
Спасибо! Мне также пришлось импортировать объект klines, но теперь он, похоже, сработал! Я все еще получаю предупреждение 1: ‹anonymous›: ... может использоваться в неправильном контексте: ‘.fun (piece, ...)’, но, просто проверив на месте созданный data.frame, он все равно кажется правильным - person Federico Marchese; 31.01.2018