Versuchen Sie immer noch, in die R-Logik einzusteigen ... Was ist der "beste" Weg, um (auf LHS) die Ergebnisse einer Funktion zu entpacken, die mehrere Werte zurückgibt?
Ich kann das anscheinend nicht machen:
R> functionReturningTwoValues <- function() { return(c(1, 2)) }
R> functionReturningTwoValues()
[1] 1 2
R> a, b <- functionReturningTwoValues()
Error: unexpected ',' in "a,"
R> c(a, b) <- functionReturningTwoValues()
Error in c(a, b) <- functionReturningTwoValues() : object 'a' not found
muss ich wirklich folgendes tun?
R> r <- functionReturningTwoValues()
R> a <- r[1]; b <- r[2]
oder würde der R-Programmierer so etwas schreiben:
R> functionReturningTwoValues <- function() {return(list(first=1, second=2))}
R> r <- functionReturningTwoValues()
R> r$first
[1] 1
R> r$second
[1] 2
--- bearbeitet, um Shane's Fragen zu beantworten ---
Ich muss den Ergebniswertteilen nicht wirklich Namen geben. Ich wende eine Aggregatfunktion auf die erste Komponente und eine andere auf die zweite Komponente an ( min
und max
wenn es für beide Komponenten dieselbe Funktion wäre, müsste ich sie nicht aufteilen).
r
return-value
variable-assignment
assign
multiple-results
Mariotomo
quelle
quelle
attr
Ihrer Information, eine andere Möglichkeit, mehrere Werte zurückzugeben, besteht darin, einen Rückgabewert festzulegen.Antworten:
(1) Liste [...] <- Ich hatte dies vor über einem Jahrzehnt auf r-help gepostet . Seitdem wurde es dem gsubfn-Paket hinzugefügt. Es ist kein spezieller Operator erforderlich, aber es ist erforderlich, dass die linke Seite folgendermaßen geschrieben wird
list[...]
:Wenn Sie nur die erste oder zweite Komponente benötigen, funktionieren diese ebenfalls:
(Natürlich, wenn Sie nur einen Wert benötigen, dann
functionReturningTwoValues()[[1]]
oderfunctionReturningTwoValues()[[2]]
wäre ausreichend.)Weitere Beispiele finden Sie im zitierten R-Help-Thread.
(2) mit Wenn die Absicht besteht, lediglich die mehreren Werte anschließend zu kombinieren und die Rückgabewerte benannt werden, besteht eine einfache Alternative darin, Folgendes zu verwenden
with
:(3) Anhängen Eine andere Alternative ist Anhängen:
HINZUGEFÜGT:
with
undattach
quelle
list
und[<-.result
wie dort gezeigt?Ich bin irgendwie auf diesen cleveren Hack im Internet gestoßen ... Ich bin mir nicht sicher, ob er böse oder schön ist, aber Sie können damit einen "magischen" Operator erstellen, mit dem Sie mehrere Rückgabewerte in ihre eigene Variable entpacken können. Die
:=
Funktion ist hier definiert und für die Nachwelt unten aufgeführt:Mit dieser Hand können Sie tun, wonach Sie suchen:
Ich weiß nicht, wie ich mich dabei fühle. Vielleicht finden Sie es in Ihrem interaktiven Arbeitsbereich hilfreich. Es ist vielleicht nicht die beste Idee, damit (wieder) verwendbare Bibliotheken (für den Massenkonsum) zu erstellen, aber ich denke, das liegt bei Ihnen.
... Sie wissen, was sie über Verantwortung und Macht sagen ...
quelle
:=
Operator mucho auf viel handlichere Weise verwendet :-)Normalerweise verpacke ich die Ausgabe in eine Liste, die sehr flexibel ist (Sie können eine beliebige Kombination von Zahlen, Zeichenfolgen, Vektoren, Matrizen, Arrays, Listen, Objekten in der Ausgabe verwenden).
So wie:
quelle
Ich denke das funktioniert.
quelle
Ich habe einen Zeallot für ein R-Paket zusammengestellt , um dieses Problem anzugehen. zeallot enthält einen Mehrfachzuweisungs- oder Auspackungszuweisungsoperator
%<-%
. Die LHS des Bedieners besteht aus einer beliebigen Anzahl von Variablen, die mithilfe von Aufrufen an zugewiesen werden sollenc()
. Die RHS des Operators ist ein Vektor, eine Liste, ein Datenrahmen, ein Datumsobjekt oder ein beliebiges benutzerdefiniertes Objekt mit einer implementiertendestructure
Methode (siehe?zeallot::destructure
).Hier sind einige Beispiele, die auf dem ursprünglichen Beitrag basieren:
Weitere Informationen und Beispiele finden Sie in der Paketvignette .
quelle
Es gibt keine richtige Antwort auf diese Frage. Ich komme wirklich darauf an, was Sie mit den Daten machen. Im obigen einfachen Beispiel würde ich dringend empfehlen:
Ist es wichtig, dass die obigen Werte 1 und 2 Namen haben? Mit anderen Worten, warum ist es in diesem Beispiel wichtig, dass 1 und 2 a und b heißen und nicht nur r [1] und r [2]? In diesem Zusammenhang ist es wichtig zu verstehen, dass a und b auch beide Vektoren der Länge 1 sind. Sie ändern also nichts wirklich, während Sie diese Zuweisung vornehmen, außer 2 neue Vektoren, für die keine Indizes erforderlich sind verwiesen werden:
Sie können die Namen auch dem ursprünglichen Vektor zuweisen, wenn Sie lieber auf den Buchstaben als auf den Index verweisen möchten:
[Bearbeiten] Da Sie min und max separat auf jeden Vektor anwenden, würde ich vorschlagen, entweder eine Matrix (wenn a und b dieselbe Länge und denselben Datentyp haben) oder einen Datenrahmen (wenn a und b gleich sind) zu verwenden die gleiche Länge, kann aber unterschiedliche Datentypen haben) oder verwenden Sie eine Liste wie in Ihrem letzten Beispiel (wenn sie unterschiedliche Längen und Datentypen haben können).
quelle
r[1]
kann helfen, die Dinge klarer zu machen (in Ordnung, nicht wenn Namen wiea
an ihre Stelle treten).Listen scheinen für diesen Zweck perfekt zu sein. Zum Beispiel innerhalb der Funktion, die Sie haben würden
Hauptprogramm
quelle
Ja zu Ihrer zweiten und dritten Frage - das müssen Sie tun, da Sie nicht mehrere 'l-Werte' links von einer Aufgabe haben können.
quelle
Wie wäre es mit Zuweisen?
Sie können die Namen der Variablen, die Sie als Referenz übergeben möchten, übergeben.
Wenn Sie die vorhandenen Werte zugreifen müssen, die Umkehrung
assign
istget
.quelle
r <- function() { return(list(first=1, second=2)) }
Verweisen Sie auf die Ergebnisse mitr$first
undr$second
.Wenn Sie die Ausgabe Ihrer Funktion an die globale Umgebung zurückgeben möchten, können Sie Folgendes verwenden
list2env
:Diese Funktion erstellt drei Objekte in Ihrer globalen Umgebung:
quelle
[A] Wenn foo und bar jeweils eine einzelne Zahl sind, ist c (foo, bar) nichts Falsches. und Sie können auch die Komponenten benennen: c (Foo = foo, Bar = bar). Sie können also auf die Komponenten des Ergebnisses 'res' als res [1], res [2] zugreifen. oder im genannten Fall als res ["Foo"], res ["BAR"].
[B] Wenn foo und bar Vektoren des gleichen Typs und der gleichen Länge sind, ist es wiederum nichts Falsches, cbind (foo, bar) oder rbind (foo, bar) zurückzugeben. ebenfalls benennbar. Im Fall 'cbind' würden Sie als res [, 1], res [, 2] oder als res [, "Foo"], res [, "Bar"] auf foo und bar zugreifen. Möglicherweise möchten Sie auch lieber einen Datenrahmen als eine Matrix zurückgeben:
und greifen Sie als res $ Foo, res $ Bar darauf zu. Dies würde auch gut funktionieren, wenn foo und bar dieselbe Länge, aber nicht denselben Typ hätten (z. B. foo ist ein Vektor von Zahlen, bar ein Vektor von Zeichenketten).
[C] Wenn foo und bar so unterschiedlich sind, dass sie nicht wie oben beschrieben kombiniert werden können, sollten Sie auf jeden Fall eine Liste zurückgeben.
Zum Beispiel könnte Ihre Funktion in ein lineares Modell passen und auch vorhergesagte Werte berechnen, so dass Sie haben könnten
und dann würden Sie
return list(Foo=foo,Bar=bar)
und dann auf die Zusammenfassung als res $ Foo zugreifen, die vorhergesagten Werte als res $ BarQuelle: http://r.789695.n4.nabble.com/How-to-return-multiple-values-in-a-function-td858528.html
quelle
Um mehrere Ausgaben von einer Funktion zu erhalten und im gewünschten Format zu halten, können Sie die Ausgaben innerhalb der Funktion auf Ihrer Festplatte (im Arbeitsverzeichnis) speichern und dann von außerhalb der Funktion laden:
quelle
Mit R 3.6.1 kann ich Folgendes tun
quelle