Rkový skript ke stažení: R
Co si zde představíme?
list
,list
Někdy jedna hodnota, vektor či matice plně nepostačují jako výstup
funkce. Řada funkcí vrací seznam několika různorodých výstupů, např.
rozklady qr
či svd
z minulého cvičení.
Z <- matrix(1:4, nrow = 2, ncol = 2)
svdZ <- svd(Z)
class(svdZ)
## [1] "list"
K uskupení spolu souvisejících objektů se používá právě
list
.
Každý prvek listu má své jméno, pod kterým jej lze získat operátorem
$
:
names(svdZ)
## [1] "d" "u" "v"
V help(svd)
se dočteme, že
d
je vektor singulárních hodnot,u
je matice levých singulárních vektorů,v
je matice pravých singulárních vektorů.Každý prvek listu lze získat operátorem $
či
[[]]
:
svdZ$d # kratší zápis
## [1] 5.4649857 0.3659662
svdZ[["u"]] # delší zápis, ale hodí se, když chceme procházet vícero prvků naráz
## [,1] [,2]
## [1,] -0.5760484 -0.8174156
## [2,] -0.8174156 0.5760484
svdZ[[3]] # lze i pomocí čísla, ale musíme znát pořadí, v jakém v listu vystupují
## [,1] [,2]
## [1,] -0.4045536 0.9145143
## [2,] -0.9145143 -0.4045536
Seznam založíme pomocí příkazu list()
, který vytvoří
úplně prázdný seznam:
seznam <- list()
Prvky do seznamu přidáváme jednoduše přižazením:
seznam$jmeno <- c("Aneta", "Bohouš", "Ctirad")
seznam$vek <- c(21, 22, 21)
seznam$vyska <- c(173, 182, 175)
seznam$vaha <- c(70, 83, 78)
seznam # defaultní print vytiskne všechny prvky (někdy až moc)
## $jmeno
## [1] "Aneta" "Bohouš" "Ctirad"
##
## $vek
## [1] 21 22 21
##
## $vyska
## [1] 173 182 175
##
## $vaha
## [1] 70 83 78
seznam$jmeno # vytiskne jen určený prvek
## [1] "Aneta" "Bohouš" "Ctirad"
seznam$vyska[2] # vytiskne druhou položku z udaného prvku
## [1] 182
Zatím je seznam
hezky uspořádaný - prvek je vždy vektor
o stejné délce. Lze jej pak jednoduše transformovat na
matrix
či data.frame
(o tom si povíme
později):
as.data.frame(seznam)
## jmeno vek vyska vaha
## 1 Aneta 21 173 70
## 2 Bohouš 22 182 83
## 3 Ctirad 21 175 78
as.matrix(as.data.frame(seznam))
## jmeno vek vyska vaha
## [1,] "Aneta" "21" "173" "70"
## [2,] "Bohouš" "22" "182" "83"
## [3,] "Ctirad" "21" "175" "78"
Při porušení struktury by nám vznikl nepřehledný nesmysl:
seznam$misto_narozeni <- c("Praha", "Brno", "Ostrava", "Klokočí")
# as.data.frame(seznam) # vrací error
seznam$misto_narozeni <- c("Praha", "Brno", "Ostrava", "Klokočí", "Křečkov", "Křenovy")
as.data.frame(seznam) # zde to sice něco vrátí, ale zdvojí se řádky, takže opatrně
## jmeno vek vyska vaha misto_narozeni
## 1 Aneta 21 173 70 Praha
## 2 Bohouš 22 182 83 Brno
## 3 Ctirad 21 175 78 Ostrava
## 4 Aneta 21 173 70 Klokočí
## 5 Bohouš 22 182 83 Křečkov
## 6 Ctirad 21 175 78 Křenovy
Neužitečného prvku seznamu se zbavíme následovně:
seznam <- within(seznam, rm("vaha")) # odstraň (rm) objekt "misto_narozeni" uvnitř seznamu, nezapomeň přeuložit
seznam$misto_narozeni <- NULL # nastav pointer na NULL - nulový objekt
seznam
## $jmeno
## [1] "Aneta" "Bohouš" "Ctirad"
##
## $vek
## [1] 21 22 21
##
## $vyska
## [1] 173 182 175
names(seznam) # v obou případech zmizí název proměnné i ze seznamu objektů
## [1] "jmeno" "vek" "vyska"
Prvkem list
u může být další list:
seznam$info <- list()
seznam$info$text <- "Data byla uměle vytvořena pro výukové účely."
seznam$info$rok <- 2025
seznam$info$autor <- list()
seznam$info$autor$jmeno <- "Jan"
seznam$info$autor$prijmeni <- "Vávra"
seznam
## $jmeno
## [1] "Aneta" "Bohouš" "Ctirad"
##
## $vek
## [1] 21 22 21
##
## $vyska
## [1] 173 182 175
##
## $info
## $info$text
## [1] "Data byla uměle vytvořena pro výukové účely."
##
## $info$rok
## [1] 2025
##
## $info$autor
## $info$autor$jmeno
## [1] "Jan"
##
## $info$autor$prijmeni
## [1] "Vávra"
seznam[["info"]][["autor"]][["prijmeni"]][1] # ke konkrétnímu prvku se dá pomocí [[]] dostat skládáním za sebe
## [1] "Vávra"
List zrušíme pomocí funkce unlist
, která pak všechen
obsah vypíše do vektoru o stejném typu:
unlist(seznam)
## jmeno1 jmeno2
## "Aneta" "Bohouš"
## jmeno3 vek1
## "Ctirad" "21"
## vek2 vek3
## "22" "21"
## vyska1 vyska2
## "173" "182"
## vyska3 info.text
## "175" "Data byla uměle vytvořena pro výukové účely."
## info.rok info.autor.jmeno
## "2025" "Jan"
## info.autor.prijmeni
## "Vávra"
Vyřešte si to sami, aniž byste se dívali do řešení (úplně dole vespod skriptu).