R zapewnia dwie różne metody dostępu do elementów listy lub data.frame: []
i [[]]
.
Jaka jest różnica między nimi, w jakich sytuacjach powinienem używać jednego nad drugim?
Definicja języka R jest przydatna w przypadku odpowiedzi na tego rodzaju pytania:
R ma trzy podstawowe operatory indeksowania, a składnia jest wyświetlana w poniższych przykładach
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
W przypadku wektorów i macierzy
[[
formy są rzadko używane, chociaż mają one pewne nieznaczne różnice semantyczne w stosunku do[
formy (np. Upuszcza wszelkie atrybuty nazw lub dimnames, a indeksowanie znaków stosuje się częściowe dopasowanie). Podczas indeksowania struktur wielowymiarowych za pomocą jednego indeksux[[i]]
lubx[i]
zwrócii
th kolejny elementx
.W przypadku list zwykle używa się
[[
do wyboru dowolnego pojedynczego elementu, a[
zwraca listę wybranych elementów.
[[
Forma pozwala tylko jeden element, który jest zaznaczony za pomocą liczb całkowitych lub postaci wskaźników, przy czym[
umożliwia indeksowanie wektorów. Należy jednak pamiętać, że dla listy indeksem może być wektor, a każdy element wektora jest stosowany kolejno do listy, wybranego komponentu, wybranego komponentu tego komponentu i tak dalej. Wynik jest nadal jednym elementem.
[
zawsze zwróci listę środków, które można uzyskać tę samą klasę wyjściowy dlax[v]
niezależnie od długościv
. Na przykład, może chciećlapply
ponad podzbiór listy:lapply(x[v], fun)
. Gdyby[
upuścić listę wektorów o długości 1, zwróciłoby to błąd, ilekroćv
ma długość 1.Istotne różnice między dwiema metodami to klasa obiektów, które zwracają, gdy są używane do ekstrakcji, oraz to, czy mogą zaakceptować zakres wartości, czy tylko jedną wartość podczas przypisywania.
Rozważ przypadek ekstrakcji danych na poniższej liście:
Powiedzmy, że chcielibyśmy wyodrębnić wartość przechowywaną przez bool z foo i użyć jej w
if()
instrukcji. Zilustruje to różnice między wartościami zwracanymi[]
i[[]]
kiedy są one używane do ekstrakcji danych. W[]
sposób powraca Przedmiotem liście klasy (lub data.frame jeśli foo był data.frame), natomiast[[]]
powraca Sposób przedmioty, których klasa jest określana przez rodzaj ich wartości.Tak więc użycie tej
[]
metody powoduje:Wynika to z tego, że
[]
metoda zwróciła listę, a lista nie jest prawidłowym obiektem do przekazania bezpośrednio doif()
instrukcji. W tym przypadku musimy użyć,[[]]
ponieważ zwróci „nagi” obiekt przechowywany w 'bool', który będzie miał odpowiednią klasę:Druga różnica polega na tym, że
[]
operator może być użyty do uzyskania dostępu do zakresu szczelin na liście lub kolumnach w ramce danych, podczas gdy[[]]
operator jest ograniczony do dostępu do pojedynczego slotu lub kolumny. Rozważ przypadek przypisania wartości za pomocą drugiej listybar()
:Powiedzmy, że chcemy zastąpić ostatnie dwa miejsca foo danymi zawartymi w takcie. Jeśli spróbujemy użyć
[[]]
operatora, dzieje się tak:Jest tak, ponieważ
[[]]
ogranicza się do uzyskania dostępu do pojedynczego elementu. Musimy użyć[]
:Zwróć uwagę, że podczas gdy przypisanie zakończyło się powodzeniem, sloty w foo zachowały swoje oryginalne nazwy.
źródło
Podwójne nawiasy otwierają dostęp do elementu listy , a pojedynczy nawias zwraca listę z jednym elementem.
źródło
Od Hadley Wickham:
Moja (kiepsko wyglądająca) modyfikacja do wyświetlania za pomocą tidyverse / purrr:
źródło
[]
wyodrębnia listę,[[]]
wyodrębnia elementy na liścieźródło
Wystarczy dodać tutaj, że
[[
jest on również przystosowany do indeksowania rekurencyjnego .Wskazano na to w odpowiedzi @JijoMatthew, ale nie zostało to zbadane.
Jak zaznaczono w
?"[["
, składnia typu jakx[[y]]
, gdzielength(y) > 1
jest interpretowana jako:Zauważ, że to nie zmienia tego, co powinno być twoim głównym wynosieniem różnicy między
[
i[[
- mianowicie, że ten pierwszy służy do podzbioru , a drugi do wyodrębniania pojedynczych elementów listy.Na przykład,
Aby uzyskać wartość 3, możemy:
Wracając do powyższej odpowiedzi @ JijoMatthew, przypomnij sobie
r
:W szczególności wyjaśnia to błędy, które często popełniamy przy niewłaściwym użyciu
[[
, a mianowicie:Ponieważ ten kod faktycznie próbował ocenić
r[[1]][[2]][[3]]
, a zagnieżdżanier
zatrzymań na poziomie pierwszym, próba wyodrębnienia za pomocą indeksowania rekurencyjnego zakończyła się niepowodzeniem[[2]]
, tj. Na poziomie 2.Tutaj R szukał
r[["foo"]][["far"]]
, który nie istnieje, więc uzyskujemy błąd indeksu poza granicami.Prawdopodobnie byłoby trochę bardziej pomocne / spójne, gdyby oba te błędy dawały ten sam komunikat.
źródło
Oba są sposobami podzbioru. Pojedynczy nawias zwróci podzbiór listy, który sam w sobie będzie listą. tzn .: może zawierać więcej niż jeden element. Z drugiej strony podwójny nawias zwróci tylko jeden element z listy.
-Jeden wspornik da nam listę. Możemy również użyć pojedynczego nawiasu, jeśli chcemy zwrócić wiele elementów z listy. rozważ następującą listę:
Teraz zwróć uwagę na sposób zwracania listy, gdy próbuję ją wyświetlić. Wpisuję r i naciskam Enter
Teraz zobaczymy magię pojedynczego nawiasu: -
co jest dokładnie takie samo, jak gdy próbowaliśmy wyświetlić wartość r na ekranie, co oznacza, że użycie pojedynczego nawiasu zwróciło listę, gdzie w indeksie 1 mamy wektor 10 elementów, a następnie mamy dwa kolejne elementy o nazwach foo i daleko. Możemy również podać pojedynczy indeks lub nazwę elementu jako dane wejściowe do pojedynczego nawiasu. na przykład:
W tym przykładzie podaliśmy jeden indeks „1”, aw zamian otrzymaliśmy listę z jednym elementem (którym jest tablica 10 liczb)
W powyższym przykładzie podaliśmy jeden indeks „2”, aw zamian otrzymaliśmy listę z jednym elementem
W tym przykładzie przekazaliśmy nazwę jednego elementu, aw zamian zwrócono listę z jednym elementem.
Możesz także przekazać wektor nazw elementów, takich jak:
W tym przykładzie przekazaliśmy wektor o dwóch nazwach elementów „foo” i „far”
W zamian otrzymaliśmy listę z dwoma elementami.
Krótko mówiąc, pojedynczy nawias zawsze zwraca kolejną listę z liczbą elementów równą liczbie elementów lub liczbie indeksów, które przekazujesz do pojedynczego nawiasu.
Natomiast podwójny nawias zawsze zwraca tylko jeden element. Przed przejściem do podwójnego nawiasu należy pamiętać o tym.
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.
Przedstawię kilka przykładów. Zapisz pogrubioną czcionkę i wróć do niej po zakończeniu poniższych przykładów:
Podwójny nawias zwróci rzeczywistą wartość w indeksie ( NIE zwróci listy)
w przypadku podwójnych nawiasów, jeśli spróbujemy wyświetlić więcej niż jeden element, przekazując wektor, spowoduje to błąd tylko dlatego, że nie został zbudowany, aby zaspokoić tę potrzebę, ale po prostu zwrócić pojedynczy element.
Rozważ następujące
źródło
Aby pomóc początkującym w poruszaniu się po ręcznej mgle, pomocne może być postrzeganie
[[ ... ]]
notacji jako funkcji zwijania - innymi słowy, to wtedy, gdy chcesz po prostu „pobrać dane” z nazwanego wektora, listy lub ramki danych. Dobrze jest to zrobić, jeśli chcesz wykorzystać dane z tych obiektów do obliczeń. Te proste przykłady to zilustrują.Tak więc z trzeciego przykładu:
źródło
iris[[1]]
zwraca wektor, podczas gdyiris[1]
zwraca data.frameBędąc terminologicznym,
[[
operator wyodrębnia element z listy, podczas gdy[
operator pobiera podzbiór listy.źródło
W jeszcze innym konkretnym przypadku użycia użyj podwójnych nawiasów, aby wybrać ramkę danych utworzoną przez
split()
funkcję. Jeśli nie wiesz,split()
grupujesz ramkę listy / danych w podzbiory na podstawie pola klucza. Jest to przydatne, jeśli chcesz operować na wielu grupach, wykreślić je itp.źródło
Proszę zapoznać się ze szczegółowym wyjaśnieniem poniżej.
Użyłem wbudowanej ramki danych w języku R, zwanej mtcars.
Górny wiersz tabeli nazywa się nagłówkiem, który zawiera nazwy kolumn. Każda linia pozioma następnie oznacza wiersz danych, który zaczyna się od nazwy wiersza, a następnie następuje rzeczywiste dane. Każdy element danych wiersza jest nazywany komórką.
operator „[]” z pojedynczym nawiasiem kwadratowym
Aby pobrać dane z komórki, wprowadzilibyśmy współrzędne jej wiersza i kolumny w operatorze „[]” z pojedynczym nawiasiem kwadratowym. Dwie współrzędne są oddzielone przecinkiem. Innymi słowy, współrzędne zaczynają się od pozycji wiersza, po której następuje przecinek, a kończy na pozycji kolumny. Kolejność jest ważna.
Np. 1: - Oto wartość komórki z pierwszego wiersza, drugiej kolumny mtcars.
Np. 2: - Ponadto możemy użyć nazw wierszy i kolumn zamiast współrzędnych numerycznych.
Podwójny nawias kwadratowy operator „[[]]”
Odwołujemy się do kolumny ramki danych za pomocą operatora podwójnego nawiasu kwadratowego „[[]]”.
Np. 1: - Aby pobrać dziewiąty wektor wbudowanego zestawu danych mtcars, piszemy mtcars [[9]].
Np. 2: - Możemy pobrać ten sam wektor kolumny według jego nazwy.
źródło
Dodatkowo:
Po LINK z ODPOWIEDŹ tutaj.
Oto mały przykład odnoszący się do następującego punktu:
x[i, j] vs x[[i, j]]
źródło