Ta strona wykorzystuje ciasteczka ("cookies") w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Czy wyrażasz na to zgodę?

Czytaj więcej
< All Topics
Print

Listy

Tworzenie list

Lista jest czymś więcej niż wektor, czynnik lub szereg czasowy. Jest zestawem obiektów o różnych typach, a mogą być nimi wektory numeryczne różnej długości, czynniki, wektory tekstowe i inne obiekty. Tworzy się poleceniem list(). Warto zwrócić uwagę na różnicę między wektorem a listą.

> w = c(1,"2")
> w
[1] "1" "2"
> w = list(1,"2")
> w
[[1]]
[1] 1[[2]]
[1] "2"

 

W listach można zapisywać kolejne wyniki różnych operacji, wyniki dodatkowych analiz (typu błędy obliczeń) oraz komentarze. Dlatego też wiele obliczeń uzyskanych za pomocą złożonych algorytmów (np. testy statystyczne) zapisuje się w obiektach typu listy. Czasem tylko część z nich jest wyświetlana po zastosowaniu takich funkcji. Natomiast po zapisaniu takiej funkcji pod nazwą jakiegoś obiektu można przeanalizować jego strukturę i dotrzeć do elementów listy, które mogą być przydatne w zastosowaniach.

Listy mogą służyć do zapisania skomplikowanych struktur jakie tworzą dane biologiczne. Oto prosty przykład związany z powtarzającymi się co jakiś czas badaniami jednej populacji: łowieniem z niej osobników, ich oznaczeniem, ważeniem, określeniem stopnia pokrewieństwa z innymi osobnikami.

> osobnik1=list(plec="samica", wiek=12, potomstwo=c("osobnik11","osobnik14"), wzrost=c(w1=2, w3=4, w6=5, w7=5.5, w10=6, w12=6))
> osobnik11=list(plec="samiec", wiek=2, potomstwo=NULL, wzrost=c(w1=2.5, w2=3.5))
> osobnik14=list(plec="samiec", wiek=1, potomstwo=NULL, wzrost=c(w1=2))
> populacja=list(osobnik1,osobnik11,osobnik14)
> populacja
[[1]]
[[1]]$plec
[1] "samica"

[[1]]$wiek
[1] 12

[[1]]$potomstwo
[1] "osobnik11" "osobnik14"

[[1]]$wzrost
w1  w3  w6  w7 w10 w12
2.0 4.0 5.0 5.5 6.0 6.0


[[2]]
[[2]]$plec
[1] "samiec"

[[2]]$wiek
[1] 2

[[2]]$potomstwo
NULL

[[2]]$wzrost
w1 w2
2.5 3.5


[[3]]
[[3]]$plec
[1] "samiec"

[[3]]$wiek
[1] 1

[[3]]$potomstwo
NULL

[[3]]$wzrost
w1
2

 

Zapis tego typu danych w postaci listy umożliwia wyciąganie różnorakiej informacji z jednego obiektu o nazwie “populacja”.

Nazywanie elementów listy

Elementy listy nie muszą być nazwane i można odwoływać się do nich poprzez nazwa[[1]], nazwa[[2]], … ale w praktyce lepiej jest je nazywać. Łatwiej jest wtedy operować tymi danymi.

Elementy listy mogą zostać nazwane w podobny sposób, jak nazywa się elementy wektora.

> w = list(liczba=1, znak="2")
> w
$liczba
[1] 1

$znak
[1] "2"

 

Gdy jako elementy listy wprowadza się nazwane wcześniej obiekty, ich nazwy nie stają się nazwami elementów listy. Trzeba je wprowadzić ponownie.

> Liczby=1:10
> Znaki=letters[1:10]
> w = list(Liczby, Znaki)
> w
[[1]]
[1]  1  2  3  4  5  6  7  8  9 10

[[2]]
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

> w = list(Liczby=Liczby, Znaki=Znaki)
> w
$Liczby
[1]  1  2  3  4  5  6  7  8  9 10

$Znaki
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

 

Listy można tworzyć nazywając obiekty składowe, których elementy zostały też nazwane. Wygląda to następująco:

> LL=list(wektor=c("A"=1,"B"=3,"C"=4),
+ czynnik=factor(c("A"=3,"B"=1,"A"=3,"A"=3)), szereg=ts(c("1maj"=1,"2maj"=2,"3maj"=3)))
> LL
$wektor
A B C
1 3 4

$czynnik
A B A A
3 1 3 3
Levels: 1 3

$szereg
Time Series:
Start = 1
End = 3
Frequency = 1
1maj 2maj 3maj
1    2    3

 

Aby wprowadzić nazwy elementów do istniejącej listy, lub zamienić na inne, można posłużyć się funkcją names().

> L=list(17,letters[1:7])
> L
[[1]]
[1] 17

[[2]]
[1] "a" "b" "c" "d" "e" "f" "g"


> names(L)=c("liczba","litery")
> L
$liczba
[1] 17

$litery
[1] "a" "b" "c" "d" "e" "f" "g"



> names(L)=c("LICZBA","LITERY")
> L
$LICZBA
[1] 17

$LITERY
[1] "a" "b" "c" "d" "e" "f" "g"


> names(L)
[1] "LICZBA" "LITERY"

 

Zastosowanie instrukcji names(L)=NULL spowoduje usunięcie nazw wszystkich elementów listy.

Listy zaimplementowane do R

Przykładem listy zaimplementowanej do R jest lista współrzędnych geograficznych środków poszczególnych stanów USA. Nosi ona nazwę state.center.

> state.center
$x
[1]  -86.7509 -127.2500 -111.6250  -92.2992 -119.7730 -105.5130 -72.3573 -74.9841 -81.6850
[10]  -83.3736 -126.2500 -113.9300  -89.3776  -86.0808 -93.3714 -98.1156  -84.7674 -92.2724
[19]  -68.9801  -76.6459  -71.5800  -84.6870  -94.6043 -89.8065 -92.5137 -109.3200 -99.5898
[28] -116.8510  -71.3924  -74.2336 -105.9420  -75.1449 -78.4686 -100.0990 -82.5963 -97.1239
[37] -120.0680  -77.4500  -71.1244  -80.5056  -99.7238 -86.4560 -98.7857 -111.3300 -72.5450
[46]  -78.2005 -119.7460  -80.6665  -89.9941 -107.2560

$y
[1] 32.5901 49.2500 34.2192 34.7336 36.5341 38.6777 41.5928 38.6777 27.8744 32.3329 31.7500
[12] 43.5648 40.0495 40.0495 41.9358 38.4204 37.3915 30.6181 45.6226 39.2778 42.3645 43.1361
[23] 46.3943 32.6758 38.3347 46.8230 41.3356 39.1063 43.3934 39.9637 34.4764 43.1361 35.4195
[34] 47.2517 40.2210 35.5053 43.9078 40.9069 41.5928 33.6190 44.3365 35.6767 31.3897 39.1063
[45] 44.2508 37.5630 47.4231 38.4204 44.5937 43.0504

 

Obiekty udostępniane w datasets programu R mają swoje strony internetowe z dodatkowymi objaśnieniami, zatem nie umieszcza się ich przy ciągach i tabelach. Wyniki niektórych opracowań statystycznych oprócz tabel wymagają czasami dodatkowych danych aby je dalej przetwarzać. Tego typu opracowanie wygodnie jest udostępnić w postaci listy. Przykładowo, lista ability.cov pokazuje wyniki obliczeń kowariancji między wynikami testów na inteligencję podzielonych na 6 kategorii i jednocześnie udostępnia wielkość próby (liczby zbadanych osób).

> ability.cov
$cov
general  picture  blocks   maze reading   vocab
general  24.641    5.991  33.520  6.023  20.755  29.701
picture   5.991    6.700  18.137  1.782   4.936   7.204
blocks   33.520   18.137 149.831 19.424  31.430  50.753
maze      6.023    1.782  19.424 12.711   4.757   9.075
reading  20.755    4.936  31.430  4.757  52.604  66.762
vocab    29.701    7.204  50.753  9.075  66.762 135.292

$center
[1] 0 0 0 0 0 0

$n.obs
[1] 112

 

Pierwszy z pokazanych obiektów jest macierzą, o której będzie mowa w następnym rozdziale.

Odwołanie się do elementów listy

Odwołanie się do elementów listy może zachodzić na dwóch poziomach.

> lista=list(1:4/5, 3:7/9, 15:20/2)
> lista
[[1]] [1] 0.2 0.4 0.6 0.8[[2]] [1] 0.3333333 0.4444444 0.5555556 0.6666667 0.7777778[[3]] [1] 7.5 8.0 8.5 9.0 9.5 10.0

> lista[2] [[1]] [1] 0.3333333 0.4444444 0.5555556 0.6666667

> lista[[2]] [1] 0.3333333 0.4444444 0.5555556 0.6666667
> lista[[2]][2] [1] 0.4444444
> lista[c(1,3)] [[1]] [1] 0.2 0.4 0.6 0.8

[[2]] [1] 7.5 8.0 8.5 9.0 9.5 10.0
> lista[c(1,3)][[2]] [1] 7.5 8.0 8.5 9.0 9.5 10.0

 

Kiedy elementy listy są nazwane, odwołanie się do poszczególnych elementów (na drugim poziomie, który daje podwójny nawias) może zachodzić poprzez nazwę. Umieszcza się ją po nazwie listy i znaku $. Jest to bardziej czytelne od podwójnego nawiasu.

> lista=list(mianownik5=1:4/5, mianownik9=3:7/9, mianownik2=15:20/2)
> lista
$mianownik5
[1] 0.2 0.4 0.6 0.8

$mianownik9
[1] 0.3333333 0.4444444 0.5555556 0.6666667 0.7777778

$mianownik2
[1] 7.5 8.0 8.5 9.0 9.5 10.0

> lista$mianownik9
[1] 0.3333333 0.4444444 0.5555556 0.6666667

 

Edycja list

Może się zdarzyć, że po utworzeniu listy trzeba w niej będzie zmienić pewne elementy. Należy dotrzeć do nich poprzez zastosowanie właściwego odwołania i w zależności od typu elementu dokonać poprawnego przypisania nowej wartości.

> L=list(liczba=7,wektor=letters[1:7], lista=list(1:3,letters[1:3]))
> L
[1] "1" "2"
$liczba
[1] 7

$wektor
[1] "a" "b" "c" "d" "e" "f" "g"

$lista
$lista[[1]]
[1] 1 2 3

$lista[[2]]
[1] "a" "b" "c"


> L[[1]]=13
> L[[2]]=letters[13:7]
> L[[3]]=list(13:10,letters[13:10])
> L
$liczba
[1] 13

$wektor
[1] "m" "l" "k" "j" "i" "h" "g"

$lista
$lista[[1]]
[1] 13 12 11 10

$lista[[2]]
[1] "m" "l" "k" "j"

 

W ten sposób można także zmieniać typ poszczególnych elementów listy.

> L=list(factor(rep(c("a","b"),5)), lista=list(1:3,letters[1:3]))
> L
[[1]]
[[1]]
[1] a b a b a b a b a b
Levels: a b

$lista
$lista[[1]]
[1] 1 2 3

$lista[[2]]
[1] "a" "b" "c"


> L[[1]]=as.vector(L[[1]])
> L[[2]]=L[[2]][2]
> L
[[1]]
[1] "a" "b" "a" "b" "a" "b" "a" "b" "a" "b"

$lista
$lista[[1]]
[1] "a" "b" "c"

 

Dodanie nowego elementu do listy najwygodniej jest przeprowadzić za pomocą funkcji append().

> L=list(cz=factor(rep(c("a","b"),3)), wek=letters[1:6])
> L
$cz
[1] a b a b a b
Levels: a b

$wek
[1] "a" "b" "c" "d" "e" "f"

> append(L,list("nowy"=1:6))
> L
$cz
[1] a b a b a b
Levels: a b

$wek
[1] "a" "b" "c" "d" "e" "f"

$nowy
[1] 1 2 3 4 5 6

> append(L,list("nowy"=1:6),1)
> L
$cz
[1] a b a b a b
Levels: a b

$nowy
[1] 1 2 3 4 5 6

$wek
[1] "a" "b" "c" "d" "e" "f"

 

Funkcja ta także łączy ze sobą różne listy.

Wykluczenie jakiegoś elementu (np. drugiego) sprowadza się do formuły Lista=Lista[-2].

Działania na listach

Gdy wśród elementów listy jest przynajmniej jeden wektor funkcja unlist() zamienia całość na wektor. Nie zawsze w ten sposób uzyska się coś sensownego. W dodatku czynniki mogą w ten sposób stracić swoje prawdziwe wartości.

> L=list(cz=factor(rep(c("a","b"),3)), sz=ts(c(1,2,3)), wek=letters[1:6])
> L
$cz
[1] a b a b a b
Levels: a b

$sz
Time Series:
Start = 1
End = 3
Frequency = 1
[1] 1 2 3

$wek
[1] "a" "b" "c" "d" "e" "f"

> unlist(L)
 cz1  cz2  cz3  cz4  cz5  cz6  sz1  sz2  sz3 wek1 wek2 wek3 wek4 wek5 wek6
"1"  "2"  "1"  "2"  "1"  "2"  "1"  "2"  "3"  "a"  "b"  "c"  "d"  "e"  "f"

 

Gdy wszystkie elementy listy są czynnikami wynikiem funkcji unlist() jest czynnik wynikający z ich połączenia.

> L=list(cz=factor(rep(c("a","b"),3)), sz=factor(1:3))
> L
$cz
[1] a b a b a b
Levels: a b

$sz
[1] 1 2 3
Levels: 1 2 3

> unlist(L)
cz1 cz2 cz3 cz4 cz5 cz6 sz1 sz2 sz3
a   b   a   b   a   b   1   2   3
Levels: a b 1 2 3

 

Połączenie szeregów czasowych w taki sposób daje wyłącznie wektor, nawet wtedy, gdy czasy kolejnych obserwacji pierwszego i drugiego szeregu umożliwiłaby utworzenie jednego, długiego szeregu czasowego.

W niektórych sytuacjach, gdy powstaje lista wyników i chce się je przekształcić, funkcja ulist() jest najlepszym sposobem na umożliwienie takich działań.

> akord=list(pon=c(35,54,50),wt=c(65,43), środ=c(44,39,55), czw=c(35,60), piat=12)
> sum(akord))
Błąd w poleceniu 'sum(akord)':niepoprawny 'type' (list) argumentu
> sum(unlist(akord))
[1] 492

 

Generalnie na listach nie wykonuje się działań matematycznych. Nie po to je wymyślono. Jednak czasem elementami listy są obiekty tego samego typu, na których możliwe są takie działania. Do ich wykonania stosuje się funkcje lapply(nazwa_listy,nazwa_funkcji). W efekcie uzyskujemy listę z wynikami działania zastosowanej funkcji na jej kolejnych elementach. Jej działanie obrazuje następujący przykład.

> L = list(a=1:4, b=5:6, c=7:9)
> L
$a
[1] 1 2 3 4

$b
[1] 5 6

$c
[1] 7 8 9

> lapply(L,sum)
$a
[1] 10

$b
[1] 11

$c
[1] 24

 

Inny przykład:

> L = list(1:7, letters[1:7])
> L
[[1]]
[1] 1 2 3 4 5 6 7

[[2]]
[1] "a" "b" "c" "d" "e" "f" "g"

> lapply(L, as.character)
[[1]]
[1] "1" "2" "3" "4" "5" "6" "7"

[[2]]
[1] "a" "b" "c" "d" "e" "f" "g"

 

Jednym z praktycznych zagadnień spotykanych przy przetwarzaniu danych jest zamiana tekstu postaci “tekst1, tekst2, tekst3,…,tekstn” (gdzie zamiast przecinków mogą być dowolne inne znaki rozdzielające) na wektor danych tekstowych c(“tekst1”, “tekst2”, “tekst3”, …, “tekstn”). Zagadnienie to dotyczy danych zapisanych w plikach tekstowych, które przy przenoszeniu do R tworzą jedną wartość tekstową. Jest to operacja odwrotna do łączenia tekstów. Do jej wykonania stosuje się funkcję strsplit(), której wartością jest lista, aczkolwiek często jest to lista jednoelementowa.

> tekst1="Ala, Ola, Ela, Ula"
> tekst2=strsplit(tekst1,"\\,")
> tekst2
[[1]]
[1] "Ala" "Ola" "Ela" "Ula"

> tekst3=unlist(tekst2)
> tekst3
[1] "Ala" "Ola" "Ela" "Ula"

 

Zapisanie wyniku w postaci listy jest uzasadnione tym, że funkcja strsplit() może działać na wektorze danych tekstowych, z których każda powinna zostać podzielona na teksty.

> tekst1=c("Ala,Ola,Ela,Ula", "Iga,Iza,Ida")
> tekst2=strsplit(tekst1,"\\,")
> tekst2
[[1]]
[1] "Ala" "Ola" "Ela" "Ula"

[[2]]
[1] "Iga" "Iza" "Ida"

> tekst3=tekst2[[1]]
> tekst3
[1] "Ala" "Ola" "Ela" "Ula"
> tekst4=tekst2[[2]]
> tekst4
[1] "Iga" "Iza" "Ida"
> tekst5=unlist(tekst2)
> tekst5
[1] "Ala" "Ola" "Ela" "Ula" "Iga" "Iza" "Ida"

 

Tags:
Spis treści