Der Unterschied zwischen Klammer [] und Doppelbügel [[]] für den Zugriff auf die Elemente einer Liste oder Datenrahmen

StackOverflow https://stackoverflow.com/questions/1169456

Frage

R bietet zwei verschiedene Methoden für die Elemente einer Liste zugreifen oder data.frame- die [] und [[]] Operatoren.

Was ist der Unterschied zwischen den beiden? In welchen Situationen sollte ich einen über den anderen?

War es hilfreich?

Lösung

Die R Sprache Definition ist praktisch, diese Art von Fragen zu beantworten:

R hat drei grundlegende Indexierungs Operatoren mit Syntax durch die folgenden Beispiele angezeigt

    x[i]
    x[i, j]
    x[[i]]
    x[[i, j]]
    x$a
    x$"a"

Für die Vektoren und Matrizen [[ Formen nur selten verwendet werden, obwohl sie einige kleine semantische Unterschiede zur [ Form haben (beispielsweise fällt es irgendwelche Namen oder dimnames Attribut, und dass eine teilweise Übereinstimmung wird für die Zeichenindizes verwendet). Wenn Indizieren mehrdimensionale Strukturen mit einem einzigen Index, x[[i]] oder x[i] das ith sequenzielle Element x zurückzukehren.

Für Listen, verwendet man im allgemeinen [[ beliebiges einzelnes Element zu wählen, während [ eine Liste der ausgewählten Elemente zurückgibt.

Die [[ Form erlaubt nur ein einziges Element Ganzzahl oder Zeichenindizes ausgewählt werden, unter Verwendung, während [ Indexieren von Vektoren ermöglicht. Man beachte aber, dass für eine Liste, kann der Index ein Vektor sein und jedes Element des Vektors ist wiederum mit der Liste, die ausgewählte Komponente, die ausgewählte Komponente dieser Komponente angewendet, und so weiter. Das Ergebnis ist immer noch ein einzelnes Element.

Andere Tipps

Die signifikanten Unterschiede zwischen den beiden Methoden sind die Klasse der Objekte, die sie zurückgeben, wenn für die Extraktion verwendet und ob können sie eine Reihe von Werten, oder einfach nur einen einzigen Wert bei der Zuordnung übernehmen.

, um den Fall der Datenextraktion auf der folgenden Liste vor:

foo <- list( str='R', vec=c(1,2,3), bool=TRUE )

Sagen wir möchten den Wert von Bool von foo gespeichert extrahieren und es in einer if() Anweisung zu verwenden. Dadurch werden die Unterschiede zwischen den Rückgabewerten von [] und [[]] zeigen, wenn sie für die Datenextraktion verwendet werden. Die Methode liefert [] Objekte der Klassenliste (oder data.frame wenn foo ein data.frame waren), während die [[]] Methode Objekte zurückgibt, deren Klasse durch die Art ihres Wertes bestimmt wird.

Also, mit der [] Methode ergibt folgend:

if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical

class( foo[ 'bool' ] )
[1] "list"

Das ist, weil die [] Methode eine Liste und eine Liste zurückgegeben wird, ist nicht gültig Objekt direkt in eine if() Anweisung übergeben. In diesem Fall müssen wir [[]] verwenden, weil es das „nackte“ Objekt in ‚Bool‘ gespeichert wird zurückkehren, die die entsprechende Klasse haben:

if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"

class( foo[[ 'bool' ]] )
[1] "logical"

Der zweite Unterschied ist, dass der [] Operator verwendet werden, um eine Bereich zuzugreifen von Schlitzen in einer Liste oder Spalten in einem Datenrahmen, während der [[]] Bediener eine , um den Zugriff auf einzelne beschränkt Schlitz oder Spalte. Betrachten wir den Fall der Wertzuweisung einer zweiten Liste mit, bar():

bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )

Sagen wir die letzten zwei Schlitze von foo mit den Daten in bar enthaltenen überschrieben werden sollen. Wenn wir versuchen, den [[]] Operator zu verwenden, das ist, was passiert:

foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar : 
more elements supplied than there are to replace

Das ist, weil [[]] für den Zugriff auf ein einzelnes Element beschränkt ist. Wir brauchen [] verwenden:

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 Zuordnung erfolgreich war, die Schlitze in foo ihren ursprünglichen Namen beibehalten.

Doppelte Klammern greifen auf eine Liste Element , während eine einzelne Konsole Ihnen wieder eine Liste mit einem einzelnen Elemente gibt.

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

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

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

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

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"

Von Hadley Wickham:

 Von Hadley Wickham

My (crappy suchen) Modifikation mit zeigen tidyverse / purrr:

 image description hier

Sie hier fügt hinzu, dass [[ auch für ausgestattet ist rekursive Indizierung .

Dies bei der Antwort von @JijoMatthew angedeutet, aber nicht untersucht.

Wie in ?"[[", Syntax wie x[[y]] erwähnt, wo length(y) > 1 wird interpretiert als:

x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]
Hinweis

, dass diese nicht ändern, was Ihr Hauptservice auf der Differenz zwischen [ und [[ sein sollte - nämlich, dass die ehemaligen für verwendet wird subsetting , und letztere wird verwendet für Extrahieren einzelne Listenelemente.

Beispiel:

x <- list(list(list(1), 2), list(list(list(3), 4), 5), 6)
x
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [1] 1
#
# [[1]][[2]]
# [1] 2
#
# [[2]]
# [[2]][[1]]
# [[2]][[1]][[1]]
# [[2]][[1]][[1]][[1]]
# [1] 3
#
# [[2]][[1]][[2]]
# [1] 4
#
# [[2]][[2]]
# [1] 5
#
# [[3]]
# [1] 6

Um den Wert 3 erhalten wir tun können:

x[[c(2, 1, 1, 1)]]
# [1] 3

Kommen wir zurück zu @ JijoMatthew Antwort oben, Rückruf r:

r <- list(1:10, foo=1, far=2)

Insbesondere dies erklärt die Fehler, die wir dazu neigen, zu erhalten, wenn eine Fehl mit [[, nämlich:

r[[1:3]]
  

Fehler in r[[1:3]]: rekursive Indizierung auf Stufe fehlgeschlagen 2

Da dieser Code tatsächlich versuchte r[[1]][[2]][[3]] zu bewerten, und die Verschachtelung des r stoppt an Stufe eins, der Versuch, durch rekursive Indizierung Extrakt bei [[2]] fehlgeschlagen ist, das heißt, auf der Ebene 2.

  

Fehler in r[[c("foo", "far")]]: Index außerhalb der Grenzen

Hier R suchte r[["foo"]][["far"]], die es nicht gibt, so erhalten wir den Index außerhalb der Grenzen Fehler.

Es wäre wahrscheinlich ein wenig hilfreicher / konsistent sein, wenn beide dieser Fehler die gleiche Botschaft gibt.

Beide sind Weisen subsetting. Die einzige Konsole wird eine Teilmenge der Liste zurück, die in sich selbst eine Liste sein. dh: Es kann oder auch nicht mehr als ein Element. Auf der anderen Seite eine doppelte Klammer kehrt nur ein einzelnes Element aus der Liste.

-Single Klammer wird uns eine Liste. Wir können auch einzelne Konsole verwenden, wenn wir mehrere Elemente aus der Liste zurückkehren wollen. Sehen Sie die folgende Liste: -

>r<-list(c(1:10),foo=1,far=2);

Bitte beachten Sie die Art und Weise der Liste zurückgegeben wird, wenn ich versuche, um es anzuzeigen. Ich tippe r und drücken Sie die Eingabetaste

>r

#the result is:-

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

$foo

[1] 1

$far

[1] 2

Jetzt werden wir die Magie der einzelnen Konsole sehen: -

>r[c(1,2,3)]

#the above command will return a list with all three elements of the actual list r as below

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

$foo

[1] 1


$far

[1] 2

, die genau das gleiche ist, wie wenn man versuchte Wert von R auf dem Bildschirm angezeigt werden, die die Verwendung von einzelner Trägereinrichtung hat eine Liste zurück, wo bei Index 1 wir einen Vektor mit 10 Elementen haben, dann haben wir zwei weitere Elemente mit Namen foo und fern. Wir können auch einen einzelnen Index oder Elementnamen als Eingabe für die einzelnen Klammer geben wählen. zB:

> r[1]

[[1]]

 [1]  1  2  3  4  5  6  7  8  9 10

In diesem Beispiel haben wir einen Index „1“ und im Gegenzug erhielt eine Liste mit einem Element (die ein Array von 10 Zahlen)

> r[2]

$foo

[1] 1

Im obigen Beispiel haben wir einen Index „2“ und im Gegenzug bekam eine Liste mit einem Element

> r["foo"];

$foo

[1] 1

In diesem Beispiel haben wir den Namen eines Elements übergeben und im Gegenzug eine Liste mit einem Element zurückgegeben.

Sie können auch einen Vektor von Elementnamen wie geben: -

> x<-c("foo","far")

> r[x];

$foo

[1] 1

$far
[1] 2

In diesem Beispiel wird ein Vektor mit zwei Elementnamen „foo“ und „weit“ bestanden

Im Gegenzug haben wir eine Liste mit zwei Elementen.

Kurz einzelne Klammer wird immer wieder zurückkehren Sie eine andere Liste mit der Anzahl der Elemente gleich der Anzahl der Elemente oder die Anzahl der Indizes Sie in den einzelnen Halter übergeben.

Im Gegensatz dazu ein Doppelbügel wird immer nur ein Element zurück. Vor seinem Wechsel zu Doppelbügel eine Notiz im Auge behalten werden. NOTE:THE MAJOR DIFFERENCE BETWEEN THE TWO IS THAT SINGLE BRACKET RETURNS YOU A LIST WITH AS MANY ELEMENTS AS YOU WISH WHILE A DOUBLE BRACKET WILL NEVER RETURN A LIST. RATHER A DOUBLE BRACKET WILL RETURN ONLY A SINGLE ELEMENT FROM THE LIST.

Ich werde Website ein paar Beispiele. Bitte halten Sie eine Notiz von den fett gedruckten Worte und kommen zurück, um es, nachdem Sie mit den folgenden Beispielen durchgeführt werden:

Doppelbügel kehren Sie den aktuellen Wert im Index. (Es wird nicht Rückkehr einer Liste)

  > r[[1]]

     [1]  1  2  3  4  5  6  7  8  9 10


  >r[["foo"]]

    [1] 1

für doppelte eckige Klammern, wenn wir, indem ein Vektor mehr Elemente zu betrachten, versuchen Sie es nur zu einem Fehler führen wird, weil es nicht auf diese Notwendigkeit gerecht zu werden wurde gebaut, aber nur ein einziges Element zurückzukehren.

Betrachten Sie das folgende

> r[[c(1:3)]]
Error in r[[c(1:3)]] : recursive indexing failed at level 2
> r[[c(1,2,3)]]
Error in r[[c(1, 2, 3)]] : recursive indexing failed at level 2
> r[[c("foo","far")]]
Error in r[[c("foo", "far")]] : subscript out of bounds

Neulinge durch den manuellen Nebel navigieren zu helfen, könnte es hilfreich sein, die [[ ... ]] Notation zu sehen, wie ein kollabierte Funktion - in anderen Worten ist es, wenn Sie wollen einfach nur ‚die Daten für‘ aus eine benannte Vektor, Liste oder Datenrahmen. Es ist gut, dies zu tun, wenn Sie Daten wollen für Berechnungen von diesen Objekten verwenden. Diese einfachen Beispiele erläutern.

(x <- c(x=1, y=2)); x[1]; x[[1]]
(x <- list(x=1, y=2, z=3)); x[1]; x[[1]]
(x <- data.frame(x=1, y=2, z=3)); x[1]; x[[1]]

So aus dem dritten Beispiel:

> 2 * x[1]
  x
1 2
> 2 * x[[1]]
[1] 2

Als terminologisches, [[ Operator Extrakte das Element aus einer Liste während [ Operators nimmt Untergruppe aus einer Liste aus.

Für noch weiteren konkreten Anwendungsfall, verwenden Sie doppelte eckige Klammern, wenn Sie durch die split() Funktion erstellt einen Datenrahmen auswählen möchten. Wenn Sie nicht wissen, split() Gruppen eine Liste / Datenrahmen in Untergruppen auf einem Schlüsselfeld basiert. Es ist sinnvoll, wenn, wenn Sie auf mehreren Gruppen betrieben werden soll, zeichnen sie, etc.

> class(data)
[1] "data.frame"

> dsplit<-split(data, data$id)
> class(dsplit)
[1] "list"

> class(dsplit['ID-1'])
[1] "list"

> class(dsplit[['ID-1']])
[1] "data.frame"

Zusätzlich:

Nach dem LINK der ANTWORT hier.

Hier ist ein kleines Beispiel den folgenden Punkt Adressierung:

x[i, j] vs x[[i, j]]

df1   <- data.frame(a = 1:3)
df1$b <- list(4:5, 6:7, 8:9)

df1[[1,2]]
df1[1,2]

str(df1[[1,2]])
str(df1[1,2])

Bitte beachten Sie die unten ausführliche Erläuterung.

Ich habe Integrierte Datenrahmen in R, genannt mtcars.

> mtcars 
               mpg cyl disp  hp drat   wt ... 
Mazda RX4     21.0   6  160 110 3.90 2.62 ... 
Mazda RX4 Wag 21.0   6  160 110 3.90 2.88 ... 
Datsun 710    22.8   4  108  93 3.85 2.32 ... 
           ............

In der oberen Zeile der Tabelle wird die Kopfzeile genannt, die die Spaltennamen enthält. Jede horizontale Linie zeigt danach eine Datenreihe, die mit dem Namen der Zeile beginnt, und dann von den tatsächlichen Daten. Jedes Datenelement einer Zeile wird eine Zelle bezeichnet wird.

einzelne eckige Klammer "[]" Operator

Um Daten in einer Zelle abrufen, würden wir die entsprechende Zeile eingeben und Spaltenkoordinaten in der Einzel eckigen Klammer „[]“ Operator. Die beiden Koordinaten werden durch ein Komma getrennt. Mit anderen Worten, beginnen die Koordinaten mit Zeilenposition, dann gefolgt von einem Komma, und endet mit der Spaltenposition. Die Reihenfolge ist wichtig.

Eg 1: - Hier ist der Zellenwert aus der ersten Zeile, zweiter Spalte des mtcars

.
> mtcars[1, 2] 
[1] 6

Zum Beispiel 2: - Darüber hinaus können wir die Zeilen- und Spaltennamen anstelle der numerischen Koordinaten verwenden

.
> mtcars["Mazda RX4", "cyl"] 
[1] 6 

Doppelte eckige Klammer "[[]]" Operator

Wir verweisen auf einen Datenrahmen Spalt mit den doppelten eckigen Klammer "[[]]" Operator.

Zum Beispiel 1: -. Um die neunte Spaltenvektor der eingebauten Daten gesetzt mtcars abrufen, schreiben wir mtcars [[9]]

  

mtcars [[9]]    [1] 1 1 1 0 0 0 0 0 0 0 0 ...

Zum Beispiel 2: -. Wir können den gleichen Spaltenvektor durch seinen Namen abrufen

  

mtcars [[ "am"]]    [1] 1 1 1 0 0 0 0 0 0 0 0 ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top