2016-07-05 6 views
0

abgerufen wird. Ich versuche meine Parallelverarbeitung in R mit dem foreach-Paket, aber es funktioniert nicht so, wie ich es möchte. Ich verwende eine Funktion, die ich selbst erstellt habe (Xenopus_Walk), die einen Vektor zurückgibt. Jetzt möchte ich diese Funktion für jede Nummer ausführen, die in einem Vektor (newly_populated_vec) gespeichert ist und eine Liste abrufen, die einen jeden Vektor speichert, der als ein Element der Liste erstellt wurde. Der Befehl, den ich bin derzeit mit dem folgenden (ich denke, man kann das meiste davon ignorieren, da das ist meist nur exportierten Pakete und Parameter meine Funktion beruht auf):Die Länge der zurückgegebenen Liste stimmt nicht mit der Länge des Vektors überein, aus dem der Iterator bei Verwendung von foreach in R

no_cores <- detectCores()-1 
cl <- makeCluster(no_cores) 
registerDoParallel(cl) 
Xenopus_Data <- foreach(b=1:length(newly_populated_vec),.combine=list,.multicombine=TRUE,.packages = c("raster", "gdistance", "rgdal","sp")) %dopar% { Xenopus_Walk(altdata=altdata,water=water,habitat_suitability=habitat_suitability,max_range_without_water=max_range_without_water,max_range=max_range,slope=slope,Start_Pt=newly_populated_vec[b]) } 

Das Problem, das ich jetzt habe, ist, dass die Länge der zurückgegebene Liste (Xenopus_Data) si unterscheidet sich von der Länge des Vektors ich den Iterator aus (newly_populated_vec) abrufen:

> length(Xenopus_Data) 
[1] 47 
> length(newly_populated_vec) 
[1] 2027 

Bei dem Versuch, herauszufinden, was falsch ist, ich habe gelesen, dass man die Arbeitsbelastung in gleich aufgeteilt hat Brocken und übergebe jeden von ihnen zu einem Kern, aber wie du wahrscheinlich mein Verständnis von allen t sein ist ziemlich niedrig. Ich habe insgesamt 32 Kerne zur Verfügung. Weiß jemand, warum ich dieses Problem habe und vielleicht auch einen Weg, es zu lösen? Ich weiß, dass reproduzierbare Beispiele gewünscht sind, aber die Funktion, die ich verwende, ist ziemlich lang und ich bezweifle, dass irgendjemand es durcharbeiten wird. Wenn ich helfen kann, die Dinge durch zusätzliche Informationen klarer zu machen, werde ich das gerne tun! Jede Art von Hilfe wird sehr geschätzt. Danke im Voraus!

BEARBEITEN: Ich habe vergessen hinzuzufügen, dass wenn ich die Liste anschaue, es verschachtelt ist, so bekomme ich nicht ein Element für jede Zahl im Vektor, aber ich bekomme ein Element mit mehreren Unterelementen. Nur für den Fall, dass das hilft.

Antwort

0

Sie sollten .combine=list nicht verwenden, da dies zu einer verschachtelten Liste führt, wenn mehr als 100 Ergebnisse vorhanden sind (es sei denn, Sie geben einen größeren Wert mit der Option .maxcombine an). Ich habe das schon einmal gesehen, aber ich bin mir ziemlich sicher, dass es immer aufgrund eines Missverständnisses funktioniert, wie die .combine Funktion funktioniert.

Das Standardverhalten besteht darin, alle Ergebnisse in einer Liste zurückzugeben, sodass Sie das Problem beheben können, indem Sie einfach die Optionen .combine und .multicombine entfernen.

Hier ist ein einfaches Beispiel, das dies zeigt:

> length(foreach(1:2027, .combine='c') %do% 1:10) 
[1] 20270 
> length(foreach(1:2027, .combine=list, .multicombine=TRUE) %do% 1:10) 
[1] 47 
> length(foreach(1:2027) %do% 1:10) 
[1] 2027 

Verwendung der Standard .combine Funktion, das Ergebnis ist immer eine Liste, deren Länge gleich der Anzahl von Aufgaben festgelegt, unabhängig von der Art der Ergebnisse.


Falls Sie interessiert sind, hier ist, wie Sie explizit definieren und eine Funktion kombinieren verwenden, die genau wie die Standard kombinieren Funktion funktioniert:

library(foreach) 
# This is defined the same as "foreach:::defcombine" 
listcomb <- function(a, ...) { 
    # concatenate new results with list of all previous results 
    c(a, list(...)) 
} 
r <- foreach(1:101, .combine='listcomb', .init=list(), 
    .multicombine=TRUE, .maxcombine=100) %do% { 
    list() 
} 

Beachten Sie, dass .init=list() so dass die angeben müssen erstes Argument zu listcomb ist eine leere Liste das erste Mal, dass listcomb aufgerufen wird. Wenn Sie dies nicht tun, wird das erste Ergebnis beschädigt, wenn es sich um eine Liste handelt.

+0

Vielen Dank für die Antwort! Ich kenne die Kombinationsoption, aber das Problem ist, dass ich die Ergebnisse weiter analysieren muss und deshalb brauche ich jeden Vektor als ein einzelnes Objekt.Wenn ich alle Vektoren in einem großen Vektor zusammenfüge, kann ich sie nicht mehr abrufen, als wenn sie in einer Liste gespeichert wären. – snoops

+0

@snoops Das Standardverhalten ist * not * zum Einfügen aller Vektoren in einen Vektor. Standardmäßig wird jedes Ergebnis als Element einer Liste zurückgegeben. Es verknüpft nur die Ergebnisse, wenn Sie '.combine =" c "' angeben. –

+0

Ok, ich dachte, da die Standardeinstellung ist, die Ausgabe der Funktion in einer Liste zu speichern, würde es keinen Unterschied machen, ob ich '.combine =" list "' schreibe oder nicht. Anscheinend habe ich mich geirrt :) Danke nochmal, dass du mir geholfen hast! – snoops