5.2 Atomické matice
Atomická matice je matice (tj. dvourozměrná tabulka), jejíž všechny prvky mají stejný datový typ (např. celé číslo). Pro datovou analýzu nejsou matice příliš důležité, někdy se však hodí pro rychlou maticovou algebru a také některé funkce vracejí nebo očekávají jako vstup matice.
Nejjednodušší způsob, jak vytvořit atomickou matici je pomocí funkce matrix()
. Prvním parametrem je vektor, který obsahuje data. Další parametry určují počet řádků a počet sloupců matice, způsob, jak budou data do matice skládaná (zda podle řádků či sloupců; implicitně se data do matic skládají po sloupcích) a pojmenování dimenzí matice. Není potřeba zadávat všechny parametry, pokud R dokáže odhadnout hodnotu jednoho parametru z hodnot ostatních parametrů. R např. umí z délky zadaného vektoru a zadaného počtu řádků odhadnout počet sloupců.
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
Při tvorbě matic R recykluje data. To znamená, že pokud je zadaných hodnot méně, než vyžadují rozměry matice, R začne číst datový vektor znovu od začátku. To může být zdrojem nepříjemných chyb. Naštěstí R vypíše varování, ovšem pouze v případě, že počet prvků matice není celočíselným násobkem délky zadaného vektoru.
## Warning in matrix(1:9, nrow = 3, ncol = 4): data length [9] is not a sub-
## multiple or multiple of the number of columns [4]
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 1
## [2,] 2 5 8 2
## [3,] 3 6 9 3
Otestovat, zda je objekt matice, je možné pomocí funkce is.matrix()
; převést data na matici je možné pomocí konverzní funkce as.matrix()
.
Zjistit rozměry matice je možné pomocí následujících funkcí: nrow()
vrátí počet řádků matice, ncol()
vrátí počet sloupců matice, dim()
vrací vektor s počtem řádků a sloupců matice a length()
vrací počet prvků matice. (Pro vektory vrací funkce nrow()
, ncol()
a dim()
hodnotu NULL
.)
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [1] 3
## [1] 4
## [1] 3 4
## [1] 12
Matice a podobné objekty je možné skládat pomocí funkcí rbind()
a cbind()
. První (rbind()
od “row bind”) spojuje matice po řádcích (tj. skládá je pod sebe), druhá (cbind()
od “column bind”) po sloupcích (tj. skládá je vedle sebe):
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [4,] 101 104 107 110
## [5,] 102 105 108 111
## [6,] 103 106 109 112
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 1 4 7 10 101 104 107 110
## [2,] 2 5 8 11 102 105 108 111
## [3,] 3 6 9 12 103 106 109 112
Matice mohou mít následující atributy: dim
je celočíselný vektor rozměrů (viz výše), jména řádků (čte i nastavuje se funkcí rownames()
), jména sloupců (čte i nastavuje se funkcí colnames()
) a jména dimenzí včetně jmen řádků a sloupců (čte i nastavuje se funkcí dimnames()
):
## alpha beta gamma delta
## a 1 4 7 10
## b 2 5 8 11
## c 3 6 9 12
## variables
## id Alpha Beta Gamma Delta
## A 1 4 7 10
## B 2 5 8 11
## C 3 6 9 12
## $dim
## [1] 3 4
##
## $dimnames
## $dimnames$id
## [1] "A" "B" "C"
##
## $dimnames$variables
## [1] "Alpha" "Beta" "Gamma" "Delta"
Atomická matice je implementována jako atomický vektor, který má přiřazený atribut dim
, který je celočíselný vektor délky dva:
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [1] TRUE
Podobně lze zrušením atributu dim
převést matici zpět na vektor (matice se vektorizuje po sloupcích). Stejného výsledku jde dosáhnout pomocí funkce as.vector()
:
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
Protože matice je atomický vektor, který má přiřazený atribut dim
, funkce is.atomic()
vrací pro matici hodnotu TRUE
; funkce is.vector()
však samozřejmě vrací FALSE
, protože testuje, zda je v proměnné uložen vektor.
## [1] TRUE
## [1] FALSE
5.2.1 Maticová aritmetika
Obyčejné symboly násobení (*
), dělení (/
) a umocňování (^
) pracují “po prvcích”. Při násobení se např. vynásobí odpovídající prvky matice. Matice tedy musejí mít stejné rozměry (stejný počet řádků a sloupců).
## variables
## id Alpha Beta Gamma Delta
## A 101 416 749 1100
## B 204 525 864 1221
## C 309 636 981 1344
## variables
## id Alpha Beta Gamma Delta
## A 1 16 49 100
## B 4 25 64 121
## C 9 36 81 144
Pro skutečné maticové násobení se používá operátor %*%
. Inverzní matici vrací funkce solve()
(obecně tato funkce řeší soustavy lineárních rovnic). K transponování matice slouží funkce t()
. Hlavní diagonálu matice vrací funkce diag()
.
Speciální matice:
## [,1] [,2] [,3]
## [1,] 1 0 0
## [2,] 0 1 0
## [3,] 0 0 1
## [,1] [,2] [,3]
## [1,] 0 0 0
## [2,] 0 0 0
## [3,] 0 0 0
Příklad inverze:
M <- matrix(c(1:8, 0), nrow = 3)
invM <- solve(M)
E <- diag(1, nrow = nrow(M), ncol = ncol(M))
all.equal(M %*% invM, E)
## [1] TRUE
## [1] TRUE
5.2.2 Subsetování matic
Subsetování matic je podobné jako u atomických vektorů s jedním rozdílem: protože má matice řádky a sloupce, je třeba subsetovat pomocí dvou indexů. První index vybírá řádky, druhý sloupce:
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
## [1] 8
## [,1] [,2]
## [1,] 1 10
## [2,] 2 11
## [,1] [,2] [,3]
## [1,] 5 8 11
## [2,] 6 9 12
Pokud je jeden z indexů prázdný, vybírá celý řádek nebo sloupec:
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [,1] [,2]
## [1,] 1 7
## [2,] 2 8
## [3,] 3 9
## [,1] [,2] [,3] [,4]
## [1,] 2 5 8 11
## [2,] 3 6 9 12
## [,1] [,2]
## [1,] 2 5
## [2,] 3 6
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
Pokud se matice indexuje jen jedním indexem, R ji tiše převede na jeden vektor (spojí sloupce matice za sebe) a vybere prvky z takto vzniklého vektoru:
## [1] 4
## [1] 1 4 5 6 7
Subsetování může nejen vybírat hodnoty, ale také měnit jejich pořadí. Zadáním indexů můžeme např. otočit pořadí sloupců matice:
## [,1] [,2] [,3] [,4]
## [1,] 8 2 6 4
## [2,] 5 3 12 9
## [3,] 7 11 1 10
## [,1] [,2] [,3] [,4]
## [1,] 4 6 2 8
## [2,] 9 12 3 5
## [3,] 10 1 11 7
Stejným způsobem můžeme dosáhnout i zajímavějších efektů: např. seřadit řádky nebo sloupce podle hodnot vybraného vektoru nebo je náhodně permutovat. Funkce order()
vrací indexy uspořádané podle velikosti původního vektoru. Funkce např. umožňuje setřídit hodnoty všech sloupců matice podle jednoho sloupce:
# indexy prvků 1. sloupce matice M seřazené podle velikosti prvků,
# tj. na 1. místě je 2. prvek původního vektoru (5), pak 3. prvek (7) atd.
order(M[, 1])
## [1] 2 3 1
## [,1] [,2] [,3] [,4]
## [1,] 5 3 12 9
## [2,] 7 11 1 10
## [3,] 8 2 6 4
Funkce sample()
náhodně permutuje zadaná čísla. Lze jí tak mimo jiné využít k náhodné permutaci sloupců matice:
## [1] 1 2 3 4
## [,1] [,2] [,3] [,4]
## [1,] 8 2 6 4
## [2,] 5 3 12 9
## [3,] 7 11 1 10
Subsetování se vždy snaží snížit rozměry matice – pokud počet řádků nebo sloupců klesne na 1, matice se změní ve vektor. Pokud tomu chceme zabránit, je třeba přidat parametr drop = FALSE
. (Nemělo by vám být divné, že je možné hranatým závorkám přidávat parametry – jako vše v R je i použití hranatých závorek volání funkce – a funkce mohou mít parametry.)
## [1] 8 5 7
## [,1]
## [1,] 8
## [2,] 5
## [3,] 7