10.4 Výběr a úpravy prvků vektorů

Často potřebujeme ze složitější struktury získat jeden její prvek. Obecně k tomu slouží funkce [[ (dvojité hranaté závorky). Funkce pluck(.x, ..., .default = NULL) tuto myšlenku zobecňuje. Umožňuje vybrat libovolně zanořený prvek vektoru .x. Ukážeme si to na příkladu vektoru hráčů:

dungeon %>% str()
## List of 2
##  $ :List of 3
##   ..$ id   : num 11
##   ..$ name : chr "Karel"
##   ..$ items:List of 2
##   .. ..$ : chr "sword"
##   .. ..$ : chr "key"
##  $ :List of 3
##   ..$ id   : num 12
##   ..$ name : chr "Emma"
##   ..$ items:List of 3
##   .. ..$ : chr "mirror"
##   .. ..$ : chr "potion"
##   .. ..$ : chr "dagger"

První parametr pluck() je vektor, ze kterého vybíráme. Další parametry jsou pozice nebo jména prvků, které vybíráme. Pokud zadáme víc položek, pak výběr funguje rekurzivně: druhá položka vybírá z výsledku prvního výběru atd.:

pluck(dungeon, 1)
## $id
## [1] 11
## 
## $name
## [1] "Karel"
## 
## $items
## $items[[1]]
## [1] "sword"
## 
## $items[[2]]
## [1] "key"
pluck(dungeon, 1, "name")
## [1] "Karel"
pluck(dungeon, 1, "items")
## [[1]]
## [1] "sword"
## 
## [[2]]
## [1] "key"
pluck(dungeon, 1, "items", 1)
## [1] "sword"

K výběru můžeme použít i funkci, která vrací výběr z vektoru:

artefact <- function(x) x[["items"]]  # funkce vrací artefakty vybraného hráče
artefact(dungeon[[1]])  # seznam všech artefaktů prvního hráče
## [[1]]
## [1] "sword"
## 
## [[2]]
## [1] "key"
pluck(dungeon, 1, artefact, 1)  # 1. artefakt prvního hráče
## [1] "sword"

Všechny tyto výběry můžeme samozřejmě provést i pomocí základních funkcí R, syntaxe pluck() je však přehlednější. Poslední výběr bychom např. museli zadat takto:

artefact(dungeon[[1]])[[1]]
## [1] "sword"

Pokud hledaný prvek ve vektoru neexistuje, funkce pluck() vrátí NULL. Tuto hodnotu můžeme změnit pomocí parametru .default:

pluck(dungeon, 3)
## NULL
pluck(dungeon, 3, .default = NA)
## [1] NA

Pokud bychom potřebovali, aby funkce raději zhavarovala, můžeme místo pluck() použít funkci chuck(x, ...):

chuck(dungeon, 3)
## Error: Index 1 exceeds the length of plucked object (3 > 2)

Funkce pluck() umožňuje i měnit hodnotu vybraného prvku (zde bohužel není možné při výběru použít funkci jako je např. naše funkce artefact()):

pluck(dungeon, 1, "items", 1) <- "megaweapon"
str(dungeon)
## List of 2
##  $ :List of 3
##   ..$ id   : num 11
##   ..$ name : chr "Karel"
##   ..$ items:List of 2
##   .. ..$ : chr "megaweapon"
##   .. ..$ : chr "key"
##  $ :List of 3
##   ..$ id   : num 12
##   ..$ name : chr "Emma"
##   ..$ items:List of 3
##   .. ..$ : chr "mirror"
##   .. ..$ : chr "potion"
##   .. ..$ : chr "dagger"

První hráč má nyní místo meče nějakou “megazbraň.”

Pokud potřebujete změnit nějaký prvek vektoru, můžete použít funkce assign_in() a modify_in(). Na jejich použití se podívejte do dokumentace.