R bietet zwei verschiedene Methoden für den Zugriff auf die Elemente einer Liste oder eines data.frame: []
y [[]]
.
Worin besteht der Unterschied zwischen den beiden, und wann sollte ich das eine dem anderen vorziehen?
R bietet zwei verschiedene Methoden für den Zugriff auf die Elemente einer Liste oder eines data.frame: []
y [[]]
.
Worin besteht der Unterschied zwischen den beiden, und wann sollte ich das eine dem anderen vorziehen?
Die Definition der R-Sprache ist für die Beantwortung dieser Art von Fragen sehr nützlich:
R verfügt über drei grundlegende Indexierungsoperatoren, deren Syntax in den folgenden Beispielen dargestellt wird
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
Für Vektoren und Matrizen wird die
[[
Formen werden nur selten verwendet, obwohl sie einige leichte semantische Unterschiede zu den[
Form (z. B. werden alle Attribute names oder dimnames weggelassen, und für Zeichenindizes wird ein partieller Abgleich verwendet). Bei der Indizierung mehrdimensionaler Strukturen mit einem einzigen Index,x[[i]]
ox[i]
gibt diei
th sequentielle Element vonx
.Für Listen verwendet man im Allgemeinen
[[
um ein einzelnes Element auszuwählen, während[
gibt eine Liste der ausgewählten Elemente zurück.Die
[[
kann nur ein einzelnes Element mit Hilfe von Ganzzahl- oder Zeichenindizes ausgewählt werden, während[
ermöglicht die Indizierung durch Vektoren. Beachten Sie jedoch, dass bei einer Liste der Index ein Vektor sein kann und jedes Element des Vektors der Reihe nach auf die Liste, die ausgewählte Komponente, die ausgewählte Komponente dieser Komponente usw. angewendet wird. Das Ergebnis ist immer noch ein einzelnes Element.
Was ist der Grund für die Verwendung von [[ vs [ mit einer einzelnen Zahl vs Vektor zu indizieren? Warum nicht einfach [ für beides verwenden? Ich schätze, man kann [[ verwenden, um einen einzelnen Eintrag zurückzubekommen, und [ mit einem Index gibt eine Liste der Länge 1 zurück... aber warum nicht einfach [ einen einzelnen Eintrag mit einem Index statt einer Liste zurückgeben lassen? Warum sollte man jemals eine Liste der Länge 1 zurückgeben wollen?
@wordsforthewise, beim Programmieren können Sie einen Vektor von unbestimmter Länge haben, den Sie für die Indizierung verwenden wollen. Mit [
immer eine Liste zurückgeben, bedeutet, dass Sie die gleiche Ausgabeklasse für x[v]
unabhängig von der Länge der v
. Zum Beispiel könnte man Folgendes wollen lapply
über eine Teilmenge einer Liste: lapply(x[v], fun)
. Si [
würde die Liste für Vektoren der Länge eins löschen, was zu einem Fehler führen würde, wenn v
hat die Länge eins.
Die wesentlichen Unterschiede zwischen den beiden Methoden sind die Klasse der Objekte, die sie zurückgeben, wenn sie für die Extraktion verwendet werden, und ob sie bei der Zuweisung einen Wertebereich oder nur einen einzelnen Wert akzeptieren können.
Betrachten Sie den Fall der Datenextraktion auf der folgenden Liste:
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
Angenommen, wir möchten den in bool gespeicherten Wert aus foo extrahieren und ihn in einer if()
Erklärung. Dies veranschaulicht die Unterschiede zwischen den Rückgabewerten von []
y [[]]
wenn sie für die Datenextraktion verwendet werden. Die Website []
Methode liefert Objekte der Klasse list (oder data.frame, wenn foo ein data.frame war), während die [[]]
Methode gibt Objekte zurück, deren Klasse durch den Typ ihrer Werte bestimmt wird.
Die Verwendung des []
Methode ergibt sich folgendes Bild:
if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical
class( foo[ 'bool' ] )
[1] "list"
Dies liegt daran, dass die []
Methode eine Liste zurück, und eine Liste ist kein gültiges Objekt, das direkt in eine if()
Anweisung. In diesem Fall müssen wir [[]]
weil es das "bloße" Objekt zurückgibt, das in 'bool' gespeichert ist und die entsprechende Klasse hat:
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
Der zweite Unterschied besteht darin, dass die []
Operator kann verwendet werden, um auf eine Bereich von Slots in einer Liste oder Spalten in einem Datenrahmen, während die [[]]
Operator ist auf den Zugriff auf eine einzeln Schlitz oder Spalte. Betrachten Sie den Fall der Wertzuweisung über eine zweite Liste, bar()
:
bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )
Angenommen, wir wollen die letzten beiden Slots von foo mit den in bar enthaltenen Daten überschreiben. Wenn wir versuchen, die [[]]
Betreiber, passiert Folgendes:
foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace
Der Grund dafür ist [[]]
ist auf den Zugriff auf ein einzelnes Element beschränkt. Wir müssen []
:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
Beachten Sie, dass die Zuweisung zwar erfolgreich war, die Slots in foo aber ihre ursprünglichen Namen behalten haben.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.