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.

  • 🧺 Przechowywanie mieszane: Lista zawiera obiekty różnych typów i długości, czego nie może zrobić zwykły wektor.
  • 🛠️. Krok kompilacji: list(vect, mat, df) pakuje wektor, macierz i ramkę danych w jeden obiekt.
  • 🔢 Dostęp do pozycji: my_list[[2]] zwraca sam element, podczas gdy my_list[2] zwraca listę jednoelementową.
  • 🏷️ Nazwane elementy: Tagowanie elementów w momencie ich tworzenia umożliwia dostęp za pomocą operatora $ lub [[„nazwa”]].
  • ✏️ Edycje na miejscu: Ponowne przypisanie aktualizuje element, a przypisanie wartości NULL usuwa go z listy.
  • 🔗 Spłaszczenie: unlist() kompresuje zagnieżdżoną listę do jednego wektora atomowego w celu dalszej analizy.

Lista R Tworzenie listy w programowaniu R i wybieranie elementów

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.

FAQ

Wektor wymusza, aby każdy element miał jeden wspólny typ, więc połączenie tekstu i liczb wymusza, aby wszystko było zgodne ze znakiem. Lista zachowuje każdy element dokładnie w takiej postaci, w jakiej został dostarczony, w tym wektory, macierze i funkcje o różnych długościach. Użyj typeof(), aby je rozróżnić.

Wywołaj metodę is.list(x), która zwraca wartość TRUE dla list i list par. Funkcja class(x) raportuje klasę obiektu, podczas gdy typeof(x) zwraca „listę” nawet dla ramek danych, ponieważ ramka danych jest listą kolumn o równej długości znajdujących się pod nią.

length(my_list) zlicza tylko elementy najwyższego poziomu, więc zagnieżdżona lista nadal liczy się jako jedna. lengths(my_list) raportuje rozmiar każdego elementu w jednym wywołaniu, co jest szybsze i bardziej przejrzyste niż looping gdy elementy są różne.

lapply(my_list, FUN) stosuje funkcjonować do każdego elementu i zwraca listę. sapply() upraszcza wynik do wektora lub macierzy, jeśli to możliwe. Prosta pętla for w seq_along(my_list) również działa i jest czytelna.

Gdy każdy element ma taką samą długość, as.data.frame(my_list) działa bezpośrednio. W przypadku listy wierszy o równej szerokości, do.call(rbind, my_list) układa je najpierw w stos. dplyr ekosystem oferuje as_tibble(), gdy typy kolumn muszą pozostać nienaruszone.

Listy nie posiadają wbudowanego sortowania, więc np.tracNajpierw użyj klucza porównywalnego: my_list[order(sapply(my_list, length))], który porządkuje elementy według rozmiaru. W przypadku danych prostokątnych przekonwertuj je na ramkę i posortuj ramkę danych zamiast tego użyj order().

Asystenci AI odczytują dane wyjściowe funkcji str() i wyjaśniają, dlaczego indeks zwrócił NULL lub podlistę zamiast wartości. Sugerują również poprawną formę nawiasów, szkicują potoki lapply() i sygnalizują ciche wymuszanie typu, zanim spowoduje to uszkodzenie wyniku.

Tak. Drugi pilot GitHub pracuje w RStudio 2023.09.0 i nowszych poprzez Narzędzia, Opcje globalne, a następnie ustawienia asystenta kodu. Uzupełnia wywołania list(), names() i unlist() z komentarza, choć każda sugestia nadal wymaga przeglądu.

Podsumuj ten post następująco: