Vor kurzem habe ich ein Objekt factor=1
in meinem Arbeitsbereich erstellt, ohne zu wissen, dass im Paket factor
eine Funktion base
vorhanden ist.
Was ich tun wollte, war, die Variable factor
innerhalb einer parallelen Schleife zu verwenden, z. B.
Dies führt jedoch zu einem Fehler, der mich so lange brauchte, um es zu verstehen. Wie es scheint, erstellt plyr
das Objekt factor
in seiner Umgebung exportEnv
, aber verwendet base::factor
anstelle des vom Benutzer bereitgestellten Objekts. Siehe das folgende Beispiel
Wenn wir die Ausgabe von llply
inspizieren, sehen wir, dass die Zeile factor_in_exportenv=get("factor",envir=export_env)
nicht 1
zurückgibt (entspricht dem vom Benutzer bereitgestellten Objekt), sondern die Funktionsdefinition von base::factor
.
Frage 1) Wie kann ich dieses Verhalten verstehen? Ich hätte erwartet, dass die Ausgabe 1
wäre.
Frage 2) Gibt es eine Möglichkeit, eine Warnung von R
zu erhalten, wenn ich einem Objekt, das bereits in einem anderen Paket definiert war (z. B. factor
), einen neuen Wert zuweise?
Zunächst sollte ich bemerken, dass der Fehler verschwindet, wenn man einen anderen Variablennamen verwendet, der nicht in base
verwendet wird - zum Beispiel, wenn wir a
anstelle von factor
verwenden. Dies zeigt deutlich, dass llply
base::factor
(eine Funktion) vor factor
(Variable mit Wert 1) entlang seines Suchpfads findet. Ich habe versucht, dieses Problem mit einer vereinfachten Version von llply
zu replizieren, d. H.
llply_simple
verwendet eine rekursive Hilfsfunktion ( allEnv
), die alle umschließenden Umgebungen durchläuft. Es gibt einen Vektor mit allen Umgebungsnamen zurück
Es ist interessant, dass die vereinfachte Funktion tatsächlich wie erwartet funktioniert (d. h. 1
und 2
als Ergebnisse liefert)
Also ist der einzige signifikante Unterschied von llply_simple
in Bezug auf die vollständige plyr::llply
-Funktion, dass letztere zu einem Paket gehört. Versuchen wir, llply_simple
in ein Paket zu verschieben.
Und nun versuchen Sie llplyTest::llply_simple
von unserem neuen Paket llplyTest
Plötzlich erhalten wir den gleichen Fehler wie in meiner ursprünglichen Frage von 2013. Das Problem ist also eindeutig mit dem Aufruf der Funktion aus einem Paket verbunden. Sehen wir uns die Ausgabe von allEnv
an: Sie gibt uns im Grunde die Abfolge der Umgebungen an, die llpy_simple
und llplyTest::llpy_simple
verwenden, um nach Variablen zu suchen, die exportiert werden sollen. Eigentlich ist es foreach
, das den Export macht und wenn man interessiert, warum foreach
wirklich mit der Umgebung beginnt, die wir llply_simple_body
genannt haben, schaut euch den Quellcode von foreach::%dopar%
, foreach:::getDoPar
und foreach:::.foreachGlobals$fun
an Folge dem Pfad des envir
-Arguments.
Wir können jetzt klar erkennen, dass die Nicht-Paket-Version eine andere Suchsequenz als llplyTest::llpy_simple
hat und dass die Paket-Version factor
in base
zuerst findet!
Die Funktion llply ruft "foreach" unter der Haube auf. Foreach verwendet "parant.frame ()", um die zu bewertende Umgebung zu bestimmen. Was ist der parant.frame im Fall von lplly? Es ist die Funktionsumgebung der llply, für die kein Faktor definiert ist.
Warum sollte fleach nicht direkt verwendet werden, anstatt llply zu verwenden?
%Vor%Beachten Sie, dass Sie den Parameter .export nicht einmal benötigen, da dies in diesem Fall automatisch der Fall ist.
Tags und Links r parallel-processing plyr