2016-08-01 74 views
0

我正在從在線API加載數據。數據分頁,因此我需要連續撥打電話。無法用foreach()使用並行化調用休息api

因此,我設置了一個最終rbind()輸出的並行foreach()循環。

下面的代碼:

library('foreach') 
    library('parallel') 
    library('jsonlite') 

    registerDoMC(cores = parallel::detectCores()) 

    data <- foreach(page = 1:10, .combine = rbind) %dopar% { 

     raw.data <- fromJSON(paste(endpoint, '&page=', page, sep ='')) 

     raw.data <- raw.data$results 

     data.piece <- raw.data[c('id', 'scraper', 'title', 'text', 'ts', 'url', 'pertinence', 'source')] 

     data.piece 
    } 

端點是一個REST URL。

循環返回NULL,並且它立即運行(每次調用確實需要幾秒鐘)。

因此看起來呼叫被跳過。如果我不是並行運行相同的代碼,它可以毫無問題地工作。

+0

您應該在上面的代碼塊之前包含您設置並行後端的代碼,以及使這個示例可重現的所有其他內容('endpoint','page'等)。 – nrussell

+0

頁面已在代碼中定義。我添加了使用過的庫。 正如我所說的端點是一個休息網址(我不能透露),但任何休息網址都可以;正如我所說的並行運行代碼(%do%而不是%dopar%),完美地工作,所以端點不是問題。 – Bakaburg

+0

如果有任何網址,那麼可以使用任何可以重現錯誤的網址來舉例說明。 – nrussell

回答

1

我碰到了類似的情況,適應我的代碼到你的情況產生以下:

library(jsonlite) 
library(dplyr) 
library(foreach) 
library(doParallel) 

fetch.data <- function(page) { 
    # confirm the url you are fetching data from ... 
    url = 'http://api.paginated/?page=' 
    endpoint = paste0(url, page) 
    print(paste0('fetching data for => ', endpoint)) 
    raw.data <- fromJSON(endpoint, flatten = TRUE) 
    raw.data 
} 


no_cores <- detectCores() 
cluster <- makeCluster(no_cores) 
registerDoParallel(cluster) 
t.start <- Sys.time() 
data <- foreach(page=1:10, .combine=bind_rows, .packages=c('jsonlite')) %dopar% { 
    if (page %% 4 == 0) Sys.sleep(1) 
    page_data <- fetch.data(page) 
    page_data <- page_data$results 
    data.piece <- page_data[c('id', 'scraper', 'title', 'text', 'ts', 'url', 'pertinence', 'source')] 
    data.piece 
} 
t.end <- Sys.time() 
stopImplicitCluster() 
print(t.end - t.start) 

此代碼最近爲我工作。唯一需要注意的是你在api的限制範圍內進行遊戲。這可能意味着你必須減慢你的腳本 - 例如,每4頁等待1秒。

+0

這是使它工作的一塊? – Bakaburg