2016-08-01 22 views
0

aufrufen Ich lade Daten von einer Online-API. Die Daten werden paginiert, so dass ich aufeinanderfolgende Anrufe tätigen muss.Kann nicht eine Ruhe-API mit foreach() mit der Parallelisierung

Deshalb habe ich eine parallelisierte foreach() Schleife eingerichtet, die schließlich die Ausgabe rbind().

Hier ist der Code:

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 
    } 

Endpoint ist eine URL REST.

Die Schleife gibt NULL zurück und außerdem läuft sie sofort (jeder Aufruf sollte in der Tat ein paar Sekunden dauern).

So scheint es, dass die Anrufe übersprungen werden. Wenn ich denselben Code nicht parallel laufe, funktioniert es ohne Probleme.

+0

Sie sollten Ihren Code, der das parallele Backend vor dem obigen Codeblock einrichtet, sowie alles andere, was erforderlich ist, um dieses Beispiel reproduzierbar zu machen ("Endpunkt", "Seite" usw.), einfügen. – nrussell

+0

Seite ist bereits im Code definiert. Ich habe die verwendeten Bibliotheken hinzugefügt. Endpunkt wie gesagt ist eine Ruhe-URL (die ich nicht offen legen kann), aber jede Ruhe-URL könnte tun; Wie ich schon sagte, läuft der Code nicht parallel (% do% anstelle von% dopar%), funktioniert einwandfrei, also ist der Endpunkt nicht das Problem. – Bakaburg

+0

Wenn eine URL erstellt wird, erstellen Sie ein Beispiel mit einer beliebigen URL, die den Fehler reproduziert. – nrussell

Antwort

1

ich in einer ähnlichen Situation gestoßen und meinen Code auf Ihre Situation anzupassen ergibt die folgende: vor kurzem für mich

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) 

Dieser Code funktioniert. Das Einzige, um das Sie sich kümmern müssen, ist, dass Sie innerhalb der Grenzen der API spielen. Dies kann bedeuten, dass Sie Ihr Skript verlangsamen müssen - zum Beispiel für jede 4. Seite 1 Sekunde warten.

+0

Welches ist das Stück, das es funktioniert? – Bakaburg