671 Stimmen

Der Unterschied zwischen Klammern [ ] und doppelten Klammern [[ ]] für den Zugriff auf die Elemente einer Liste oder eines Datenrahmens

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?

419voto

ars Punkte 112843

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]] o x[i] gibt die i th sequentielle Element von x .

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.

10 Stimmen

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?

11 Stimmen

@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.

8 Stimmen

Ich denke, das erklärt alles besser, adv-r.had.co.nz/Subsetting.html

208voto

Sharpie Punkte 16663

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.

147voto

medriscoll Punkte 25767

Doppelte Klammern greifen auf eine Liste zu Element , während eine einzelne Klammer eine Liste mit einem einzigen Element zurückgibt.

lst <- list('one','two','three')

a <- lst[1]
class(a)
## returns "list"

a <- lst[[1]]
class(a)
## returns "character"

129voto

jzadra Punkte 3411

Von Hadley Wickham:

From Hadley Wickham

Meine (beschissen aussehende) Modifikation, um die Verwendung von tidyverse / purrr zu zeigen:

enter image description here

4 Stimmen

Super! Sie haben einige von Grace Hoppers Pikosekunden !

0 Stimmen

@StevePitchers huh?

3 Stimmen

Grace Hopper bei Letterman, die Nanosekunden demonstriert dailymotion.com/video/x35dsz7 .

62voto

[] extrahiert eine Liste, [[]] extrahiert Elemente innerhalb der Liste

alist <- list(c("a", "b", "c"), c(1,2,3,4), c(8e6, 5.2e9, -9.3e7))

str(alist[[1]])
 chr [1:3] "a" "b" "c"

str(alist[1])
List of 1
 $ : chr [1:3] "a" "b" "c"

str(alist[[1]][1])
 chr "a"

CodeJaeger.com

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.

Powered by:

X