Listy w programowaniu R: jak tworzyć i wybierać elementy
⚡ Inteligentne podsumowanie
R List to obiekt, który przechowuje wektory, macierze, ramki danych, a nawet inne listy w jednym kontenerze. Funkcja list() go buduje, a podwójne nawiasy kwadratowe wyciągają dowolny element.
Co to jest lista R?
Lista R to obiekt w języku R, który zawiera macierze, wektory, ramki danych lub listy. Lista R służy również do przechowywania kolekcji obiektów i korzystania z nich, gdy ich potrzebujemy. Możemy sobie wyobrazić listę R jako torbę do przechowywania wielu różnych przedmiotów. Kiedy potrzebujemy jakiegoś przedmiotu, możemy otworzyć torbę i skorzystać z niego.
Kontrast z wektorem sprawia, że torba jest użyteczna. Wektor wymusza każdy element jednego typu, więc umieszczenie słowa obok liczby zamienia liczbę w tekst. Lista nie stosuje takiej reguły, dlatego może zawierać wektor pięcioelementowy, dwuwierszowy. matryca i ramkę danych składającą się z 714 wierszy obok siebie, bez zmiany żadnego z nich.
Składnia listy w R
Do tworzenia list w programowaniu R możemy użyć funkcji list():
list(element_1, ...) arguments: -element_1: store any type of R object -...: pass as many objects as specifying. each object needs to be separated by a comma
Każdy argument może być przekazany w postaci czystej lub w formie znacznik = wartość. Argument pusty staje się elementem pozycyjnym, do którego można dotrzeć tylko za pomocą jego numeru, podczas gdy argument oznaczony również zyskuje nazwę. Podstawowa referencja R dla lista() dokumentuje oba formularze i zauważa, że unlist() działa jako przybliżona odwrotność as.list().
Jak utworzyć listę w R
Poniżej znajduje się krok po kroku proces tworzenia listy w R:
W poniższym przykładzie utworzymy trzy różne obiekty: wektor, macierz i a Ramka danych używając funkcji list w R.
Krok 1) Utwórz wektor
Użyj poniższego kodu, aby utworzyć wektor w R
# Vector with numeric from 1 up to 5
vect <- 1:5
Operator dwukropka tworzy sekwencję 1, 2, 3, 4, 5 jako wektor całkowity, a strzałka przypisania zapisuje go pod nazwą vect.
Krok 2) Utwórz macierz
Teraz utwórz macierz, korzystając z następującego kodu
# A 2x 5 matrix
mat <- matrix(1:9, ncol = 5)
dim(mat)
Na uwagę zasługują dwa szczegóły. Siatka o wymiarach dwóch wierszy na pięć kolumn wymaga dziesięciu wartości, a mimo to podano tylko dziewięć, więc R przetwarza sekwencję i wyświetla ostrzeżenie, że długość danych nie jest podwielokrotnością liczby wierszy. Ta przetworzona wartość powoduje, że drugi wiersz drukowanej macierzy kończy się cyfrą 1, a nie 10. Wywołanie funkcji dim() następnie raportuje kształt.
Wyjście:
## [1] 2 5
Krok 3) Utwórz ramkę danych
Utwórz ramkę danych w R, używając poniższego kodu
# select the 10th row of the built-in R data set EuStockMarkets
df <- EuStockMarkets[1:10,]
Komentarz wspomina o dziesiątym wierszu, ale wyrażenie zachowuje wiersze od 1 do 10 wbudowanej serii EuStockMarkets. Podzbiór usuwa również klasę szeregów czasowych, więc zwracana jest macierz numeryczna, a nie prawdziwa ramka danych. Właśnie dlatego poniższy wydruk zawiera etykiety wierszy w stylu [1,] zamiast nazw wierszy. Zawiń wywołanie w as.data.frame() zawsze, gdy potrzebna jest prawdziwa ramka danych.
Krok 4) Utwórz listę w R
Teraz możemy umieścić trzy obiekty na liście R, używając poniższego kodu
# Construct list with these vec, mat, and df:
my_list <- list(vect, mat, df)
my_list
Wyjście:
## [[1]] ## [1] 1 2 3 4 5 ## [[2]] ## [,1] [,2] [,3] [,4] [,5] ## [1,] 1 3 5 7 9 ## [2,] 2 4 6 8 1 ## [[3]] ## DAX SMI CAC FTSE ## [1,] 1628.75 1678.1 1772.8 2443.6 ## [2,] 1613.63 1688.5 1750.5 2460.2 ## [3,] 1606.51 1678.6 1718.0 2448.2 ## [4,] 1621.04 1684.1 1708.1 2470.4 ## [5,] 1618.16 1686.6 1723.1 2484.7 ## [6,] 1610.61 1671.6 1714.3 2466.8 ## [7,] 1630.75 1682.9 1734.5 2487.9 ## [8,] 1640.17 1703.6 1757.4 2508.4 ## [9,] 1635.47 1697.5 1754.0 2510.5 ## [10,] 1645.89 1716.3 1754.3 2497.4
Trzy nagłówki z podwójnymi nawiasami kwadratowymi w tym wyniku to pozycje na liście. Nic nie zostało spłaszczone ani wymuszone: element pierwszy nadal jest wektorem całkowitym, element drugi nadal jest macierzą, a element trzeci nadal zawiera wszystkie dziesięć wierszy cen akcji.
Wybierz elementy z listy R
Po utworzeniu listy możemy uzyskać do niej dostęp dość łatwo. Aby wybrać element z listy, musimy użyć [[index]]. Wartość w podwójnym nawiasie kwadratowym reprezentuje pozycję elementu na liście, który chcemy wybrać.tract. Na przykład, jeśli podajemy 2 w nawiasie, R zwróci drugi wymieniony element.
Teraz w tym Poradnik R, spróbujmy wybrać drugie elementy list w R o nazwie moja_lista, używamy moja_lista[[2]]
# Print second element of the list
my_list[[2]]
Wyjście:
## [,1] [,2] [,3] [,4] [,5] ## [1,] 1 3 5 7 9 ## [2,] 2 4 6 8 1
Pojedyncze i podwójne nawiasy nie są zamienne, a ich mylenie jest najczęstszą przyczyną błędów w listach. Jeden nawias zachowuje otoczkę, dwa nawiasy ją usuwają.
| Wyrażenie | Co wraca | Klasa wyniku | Użyj tego, kiedy |
|---|---|---|---|
| moja_lista[[2]] | Sam zapisany element | Cokolwiek zostało zapisane, tutaj jest macierz | Musisz wykonać obliczenia na jednym elemencie |
| moja_lista[2] | Podlista zawierająca ten jeden element | podstęp | Musisz zachować opakowanie listy |
| moja_lista[c(1, 3)] | Podlista wybranych elementów | podstęp | Potrzebujesz kilku elementów na raz |
| moja_lista[-2] | Każdy element oprócz drugiego | podstęp | Musisz usunąć element |
# Compare the two bracket styles class(my_list[[2]]) # the matrix itself class(my_list[2]) # a list of length one # Several elements, and everything but one element my_list[c(1, 3)] my_list[-2]
Listy nazwane w R
Indeksy pozycyjne są delikatne: wstawia się jeden element i każdą liczbę po jego przesunięciu. Nadanie nazw elementom eliminuje to ryzyko i sprawia, że kod czyta się jak dane, które opisuje. Nazwy można podać podczas tworzenia listy lub dołączyć później za pomocą names().
# Tag each element at creation time named_list <- list(numbers = vect, grid = mat, prices = df) # Three ways to reach the same element named_list$grid named_list[["grid"]] named_list["grid"] # returns a one-element list # Read or replace the names later names(named_list) names(named_list)[2] <- "grid_2x5"
Operator $ i podwójny nawias klamrowy różnią się pod jednym względem, który zaskakuje początkujących. Operator $ wykonuje dopasowanie częściowe, więc named_list$pri nadal znajduje ceny, podczas gdy named_list[[“pri”]] zwraca NULL, ponieważ podwójne nawiasy klamrowe pasują dokładnie, chyba że podano wartość exact = FALSE. Dopasowanie częściowe jest wygodne w konsoli, ale niebezpieczne w skrypcie, dlatego w zapisanym kodzie należy preferować formę dokładną.
# A compact map of the whole structure
str(named_list)
str() drukuje jeden wiersz na element z jego typem i rozmiarem, co jest najszybszym sposobem potwierdzenia, że lista zawiera to, czego się spodziewasz, przed jej indeksowaniem.
Modyfikuj, dodawaj i usuwaj elementy na liście R
Lista nie jest ustalona po utworzeniu. Te same akcesory, które odczytują element, również do niego zapisują, więc aktualizowanie, rozszerzanie i zmniejszanie listy odbywa się za pomocą zwykłego przypisania.
# Replace an element in place named_list[["numbers"]] <- 1:10 # Add a new element simply by naming it named_list[["created"]] <- Sys.Date() # Append without a name: the element lands at the end named_list <- append(named_list, list(TRUE)) # Delete an element by assigning NULL to it named_list[["created"]] <- NULL
- Zastąpić: przypisanie do istniejącej nazwy powoduje nadpisanie danego elementu i pozostawienie jego pozycji niezmienionej.
- Dodaj: przypisanie do nazwy, która nie istnieje, powoduje dodanie nowego elementu na końcu listy.
- Dodać: append() przyjmuje listę jako drugi argument, więc przed przekazaniem jej należy umieścić ją w list().
- Kasować: przypisanie wartości NULL za pomocą podwójnych nawiasów powoduje usunięcie elementu i skrócenie listy.
Jedna konsekwencja, która często zawodzi: ponieważ NULL oznacza usunięcie, nie można zapisać rzeczywistego NULL za pomocą podwójnych nawiasów. Zamiast tego należy użyć przypisania w pojedynczym nawiasie, jak w named_list[“empty”] <- list(NULL), które zachowuje slot i umieszcza w nim NULL.
Zagnieżdżone listy i unlist() w R
Ponieważ lista może zawierać dowolny obiekt R, może również zawierać inną listę. Zagnieżdżanie to sposób, w jaki obiekty konfiguracyjne, odpowiedzi JSON i wyniki modeli są zazwyczaj reprezentowane w R, więc sięganie do zagnieżdżonej listy i spłaszczanie jej to codzienne zadania.
# A list whose elements are themselves lists project <- list( meta = list(owner = "analyst", year = 2026), data = list(vect, mat) ) # Chain the accessors to reach an inner value project$meta$year project[["data"]][[2]] # Flatten every level into one atomic vector flat <- unlist(project) # Strip a single level and keep the rest as a list half <- unlist(project, recursive = FALSE)
Spłaszczanie ma swoją cenę, którą warto zrozumieć. Funkcja unlist() musi zwrócić jeden wektor atomowy, więc wymusza każdą wartość do najogólniejszego typu, zgodnie z kolejnością: logiczna, całkowita, zmiennoprzecinkowa, znakowa. Lista zagnieżdżona, która łączy liczby z tekstem, zwraca zatem wyłącznie tekst. Nazwy wyników są tworzone poprzez połączenie znaczników zewnętrznego i wewnętrznego, dlatego element jest dostarczany jako meta.owner, a nie owner.
Przekaż use.names = FALSE, gdy te złożone nazwy są niepożądane, i ustaw recursive = FALSE, gdy należy usunąć tylko najbardziej zewnętrzną warstwę. Jeśli wartości muszą zachować swoje typy, pozostaw strukturę nienaruszoną i przeanalizuj listę zamiast ją spłaszczać.
Wbudowana ramka danych w R
Listy są często wypełniane danymi odczytanymi z dysku lub z internetu, dlatego warto zobaczyć, jak ramka danych dociera do odbiorcy, zanim zostanie w niej zapisana. Zanim utworzymy własną ramkę danych, możemy zapoznać się z dostępnym online zestawem danych R. Zbiór danych więziennych ma wymiary 714×5. Możemy szybko zobaczyć dolną część ramki danych za pomocą funkcji tail(). Analogicznie, funkcja head() wyświetla górną część ramki danych. Liczbę wyświetlanych wierszy można określić za pomocą funkcji head(df, 5). Więcej informacji o funkcji read.csv() poznamy w… importuj dane w R poradnik.
PATH <-'https://raw.githubusercontent.com/guru99-edu/R-Programming/master/prison.csv'
df <- read.csv(PATH)[1:5]
head(df, 5)
Wyjście:
## X state year govelec black ## 1 1 1 80 0 0.2560 ## 2 2 1 81 0 0.2557 ## 3 3 1 82 1 0.2554 ## 4 4 1 83 0 0.2551 ## 5 5 1 84 0 0.2548
Polecenie [1:5] następujące po read.csv() wybiera pierwsze pięć kolumn, a nie pierwsze pięć wierszy, ponieważ ramka danych sama w sobie jest listą kolumn. Indeksowanie listy za pomocą pojedynczych nawiasów klamrowych zwraca mniejszą listę, która w tym przypadku nadal jest ramką danych.
Możemy sprawdzić strukturę ramki danych za pomocą str:
# Structure of the data
str(df)
Wyjście:
## 'data.frame': 714 obs. of 5 variables: ## $ X : int 1 2 3 4 5 6 7 8 9 10 ... ## $ state : int 1 1 1 1 1 1 1 1 1 1 ... ## $ year : int 80 81 82 83 84 85 86 87 88 89 ... ## $ govelec: int 0 0 1 0 0 0 1 0 0 0 ... ## $ black : num 0.256 0.256 0.255 0.255 0.255 ...
Wszystkie zmienne są przechowywane w pliku liczbowy Format. Prefiks $ w każdym wierszu to ten sam operator, który był wcześniej używany na nazwanych listach, co potwierdza, że ramka danych to lista kolumn o równej długości oznaczonych prostokątną etykietą. Cała wiedza na temat nadawania nazw, zaznaczania i usuwania elementów listy przenosi się zatem bezpośrednio do Typy danych R i do kolumn ramek danych.

