Obsah
1. Programovací jazyk R: pole a další podporované datové typy
2. Konstrukce jednorozměrného a dvojrozměrného pole
3. Plnohodnotná dvojrozměrná pole
4. Chování ve chvíli, kdy zdrojový vektor neobsahuje dostatečný počet prvků
6. Opakování prvků při konstrukci trojrozměrných polí
7. Pojmenování řádků a sloupců pole
8. Pojmenování třetí dimenze trojrozměrného pole
10. Pojmenování třetí a čtvrté dimenze čtyřrozměrného pole
11. Přístup k prvkům dvojrozměrného pole
12. Získání celého řádku dvojrozměrného pole
13. Získání celého sloupce dvojrozměrného pole
14. Záporné indexy při přístupu k prvkům pole
15. Filtrace řádků při výběru s využitím záporných indexů
16. Filtrace sloupců při výběru s využitím záporných indexů
17. Operace provedená nad korespondujícími prvky dvou polí
18. Od dvojrozměrných polí k maticím
19. Repositář s demonstračními příklady
1. Programovací jazyk R: pole a další podporované datové typy
Ve druhé části seriálu o doménově specifickém programovacím jazyku R jsme se zabývali popisem práce s primárním datovým typem tohoto jazyka. Připomeňme si, že se jednalo o vektory (vector), což je homogenní a současně i měnitelný (mutable) datový typ, který může obsahovat logické hodnoty, celá čísla, čísla s plovoucí čárkou, komplexní čísla, popř. řetězce. Ovšem v jazyku R je možné pracovat i s hodnotami, které jsou odlišného datového typu. A právě s těmito dalšími typy se seznámíme dnes. Při popisu všech datových typů budeme opět používat relativně velké množství demonstračních příkladů, které je možné buď zapsat přímo do konzole jazyka R, použít jednoduchá IDE dostupná online [1] [2] [3] nebo pro jejich spuštění použít nástroj Rscript (ten je součástí standardní sady nástrojů jazyka R):
$ Rscript Usage: /path/to/Rscript [--options] [-e expr [-e expr2 ...] | file] [args] --options accepted are --help Print usage and exit --version Print version and exit --verbose Print information on progress --default-packages=list Where 'list' is a comma-separated set of package names, or 'NULL' or options to R, in addition to --no-echo --no-restore, such as --save Do save workspace at the end of the session --no-environ Don't read the site and user environment files --no-site-file Don't read the site-wide Rprofile --no-init-file Don't read the user R profile --restore Do restore previously saved objects at startup --vanilla Combine --no-save, --no-restore, --no-site-file --no-init-file and --no-environ 'file' may contain spaces but not shell metacharacters Expressions (one or more '-e <expr>') may be used *instead* of 'file' See also ?Rscript from within R
2. Konstrukce jednorozměrného a dvojrozměrného pole
V této kapitole si ukážeme způsob konstrukce jednorozměrného a dvojrozměrného pole. Jednorozměrné pole je ve skutečnosti vektorem, který má ovšem specifikován atribut dim, což je další vektor obsahující specifikaci informace o dimenzích pole. Pokud například pole vytvoříme ze šestiprvkového vektoru a vektor s dimenzemi bude jednoprvkový c(6), vytvoří se jednorozměrné pole se šesticí prvků. Povšimněte si způsobu konstrukce pole pomocí funkce array:
> data <- c(1, 2, 3, 4, 5, 6) > dimension1 <- c(6) > > a1 <- array(data, dim=dimension1) > print(a1) [1] 1 2 3 4 5 6
Dimenzi pole lze získat funkcí dim:
> print(dim(a1)) [1] 6
Alternativně je ovšem možné pole vytvořit i zdánlivým přiřazením hodnoty do návratové hodnoty funkce dim(a1):
> a1 <- c(1, 2, 3, 4, 5, 6) > print(a1) > dim(a1) <- c(6) > print(a1)
Nyní si ukažme vytvoření pole s jedním řádkem a šesti sloupci:
> data <- c(1, 2, 3, 4, 5, 6) > dimension2 <- c(1, 6) > > a2 <- array(data, dim=dimension2) > print(a2) [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 2 3 4 5 6
Naopak pole se šesti řádky a jedním sloupcem (sloupcový vektor) se vytvoří:
> data <- c(1, 2, 3, 4, 5, 6) > dimension2 <- c(6, 1) > > a2 <- array(data, dim=dimension2) > print(a2) [1] 1 2 3 4 5 6 [,1] [1,] 1 [2,] 2 [3,] 3 [4,] 4 [5,] 5 [6,] 6
Popř.:
> a2 <- c(1, 2, 3, 4, 5, 6) > print(a2) > dimension2 <- c(1, 6) > dim(a2) <- dimension2 > print(a2)
3. Plnohodnotná dvojrozměrná pole
Nyní si ukažme konstrukci dvojrozměrného pole se třemi řádky a dvěma sloupci:
> data <- c(1, 2, 3, 4, 5, 6) > dimension1 <- c(3, 2) > > a1 <- array(data, dim=dimension1) > print(a1) [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6
A naopak – pole se třemi sloupci a dvěma řádky:
> > dimension2 <- c(2, 3) > > a2 <- array(data, dim=dimension2) > print(a2) [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6
Alternativní způsob se specifikací dimenze pole až po jeho vytvoření:
data <- c(1, 2, 3, 4, 5, 6) dimension1 <- c(3, 2) a1 <- array(data, dim=dimension1) print(a1) dimension2 <- c(2, 3) a2 <- array(data, dim=dimension2) print(a2)
Samozřejmě můžeme vektor představující zdroj dat vytvořit i s využitím range, tedy zápisu prvek1:prvekN:
> data <- 1:12 > dimension1 <- c(3, 4) > > a1 <- array(data, dim=dimension1) > print(a1) [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 > dimension2 <- c(4, 3) > > a2 <- array(data, dim=dimension2) > print(a2) [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12
4. Chování ve chvíli, kdy zdrojový vektor neobsahuje dostatečný počet prvků
V dalším demonstračním příkladu se pokusíme vytvořit pole 3×4 prvky, ovšem zdrojem bude vektor obsahující pouze trojici prvků. Nejedná se o chybu, protože v tomto případě dojde k opakování prvků zdrojového vektoru až do chvíle, kdy se výsledné pole zcela naplní:
> data <- 1:3 > dimension1 <- c(3, 4) > > a1 <- array(data, dim=dimension1) > print(a1) [,1] [,2] [,3] [,4] [1,] 1 1 1 1 [2,] 2 2 2 2 [3,] 3 3 3 3
Dtto při pokusu o vytvoření pole s rozměry 4×3 prvky:
> > data <- 1:4 > dimension2 <- c(4, 3) > > a2 <- array(data, dim=dimension2) > print(a2) [,1] [,2] [,3] [1,] 1 1 1 [2,] 2 2 2 [3,] 3 3 3 [4,] 4 4 4
Tohoto chování můžeme využít při konstrukci pole, které obsahuje pouze nulové prvky (nebo samozřejmě jinou konstantní hodnotu):
data <- 0 dimension1 <- c(3, 4) a1 <- array(data, dim=dimension1) print(a1) data <- 0 dimension2 <- c(4, 3) a2 <- array(data, dim=dimension2) print(a2)
S výsledky:
[,1] [,2] [,3] [,4] [1,] 0 0 0 0 [2,] 0 0 0 0 [3,] 0 0 0 0 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 [3,] 0 0 0 [4,] 0 0 0
5. Pole se třemi dimenzemi
Pole může být i vícedimenzionální. V dalším demonstračním příkladu postupně vytvoříme pole o rozměrech 2×3×4 prvky, 3×2×4 prvky a konečně 4×3×2 prvky. Ve všech případech bude zdrojem hodnot prvků vektor obsahující celočíselné hodnoty 1, 2, … 24 (což přesně odpovídá požadovanému počtu prvků výsledných trojrozměrných polí):
> data <- 1:24 > > print("2x3x4") [1] "2x3x4" > dimension1 <- c(2, 3, 4) > a1 <- array(data, dim=dimension1) > print(a1) , , 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 , , 3 [,1] [,2] [,3] [1,] 13 15 17 [2,] 14 16 18 , , 4 [,1] [,2] [,3] [1,] 19 21 23 [2,] 20 22 24
Změna tvaru pole:
> print("3x2x4") [1] "3x2x4" > dimension2 <- c(3, 2, 4) > a2 <- array(data, dim=dimension2) > print(a2) , , 1 [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 , , 2 [,1] [,2] [1,] 7 10 [2,] 8 11 [3,] 9 12 , , 3 [,1] [,2] [1,] 13 16 [2,] 14 17 [3,] 15 18 , , 4 [,1] [,2] [1,] 19 22 [2,] 20 23 [3,] 21 24
A poslední změna tvaru pole:
> print("4x3x2") [1] "4x3x2" > dimension3 <- c(4, 3, 2) > a3 <- array(data, dim=dimension3) > print(a3) , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 13 17 21 [2,] 14 18 22 [3,] 15 19 23 [4,] 16 20 24
Alternativně je ovšem možné dimenzi specifikovat až přiřazením do existujícího vektoru:
print("2x3x4") a1 <- 1:24 dimension1 <- c(2, 3, 4) dim(a1) <- dimension1 print(a1) print("3x2x4") a2 <- 1:24 dimension2 <- c(3, 2, 4) dim(a2) <- dimension2 print(a2) print("4x3x2") a3 <- 1:24 dimension3 <- c(4, 3, 2) dim(a3) <- dimension3 print(a3)
Výsledky budou v tomto případě odpovídat předchozím třem příkladům.
6. Opakování prvků při konstrukci trojrozměrných polí
Opět si ukažme chování programovacího jazyka R ve chvíli, kdy zdrojový vektor nebude obsahovat všechny potřebné prvky:
data <- 1:12
Vektor obsahuje pouze dvanáct prvků, ovšem vyžadujeme konstrukci trojrozměrného pole s celkem 24 prvky. Prvky se tedy musí opakovat:
> print("2x3x4") [1] "2x3x4" > dimension1 <- c(2, 3, 4) > a1 <- array(data, dim=dimension1) > print(a1) , , 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 , , 3 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 4 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12
Dtto pro odlišný tvar trojrozměrného pole:
> print("3x2x4") [1] "3x2x4" > dimension2 <- c(3, 2, 4) > a2 <- array(data, dim=dimension2) > print(a2) , , 1 [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 , , 2 [,1] [,2] [1,] 7 10 [2,] 8 11 [3,] 9 12 , , 3 [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 , , 4 [,1] [,2] [1,] 7 10 [2,] 8 11 [3,] 9 12
Poslední varianta:
> print("4x3x2") [1] "4x3x2" > dimension3 <- c(4, 3, 2) > a3 <- array(data, dim=dimension3) > print(a3) , , 1 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 , , 2 [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12
Alternativní způsob zápisu – specifikace dimenze původně jednorozměrného vektoru:
data <- 1:12 print("2x3x4") dimension1 <- c(2, 3, 4) a1 <- array(data, dim=dimension1) print(a1) print("3x2x4") dimension2 <- c(3, 2, 4) a2 <- array(data, dim=dimension2) print(a2) print("4x3x2") dimension3 <- c(4, 3, 2) a3 <- array(data, dim=dimension3) print(a3)
A konečně naplnění trojrozměrného pole nulami:
data <- 0 print("2x3x4") dimension1 <- c(2, 3, 4) a1 <- array(data, dim=dimension1) print(a1) print("3x2x4") dimension2 <- c(3, 2, 4) a2 <- array(data, dim=dimension2) print(a2) print("4x3x2") dimension3 <- c(4, 3, 2) a3 <- array(data, dim=dimension3) print(a3)
S výsledky:
[1] "2x3x4" , , 1 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 , , 2 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 , , 3 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 , , 4 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 [1] "3x2x4" , , 1 [,1] [,2] [1,] 0 0 [2,] 0 0 [3,] 0 0 , , 2 [,1] [,2] [1,] 0 0 [2,] 0 0 [3,] 0 0 , , 3 [,1] [,2] [1,] 0 0 [2,] 0 0 [3,] 0 0 , , 4 [,1] [,2] [1,] 0 0 [2,] 0 0 [3,] 0 0 [1] "4x3x2" , , 1 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 [3,] 0 0 0 [4,] 0 0 0 , , 2 [,1] [,2] [,3] [1,] 0 0 0 [2,] 0 0 0 [3,] 0 0 0 [4,] 0 0 0
7. Pojmenování řádků a sloupců pole
Řádky, popř. sloupce pole je možné pojmenovat, což může být v praxi poměrně užitečné. Jména řádků jsou uložena do samostatného vektoru, stejně jako jména sloupců. Způsob nastavení je ukázán na následujícím demonstračním příkladu:
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12
8. Pojmenování třetí dimenze trojrozměrného pole
Pojmenovat lze i vyšší dimenze trojrozměrných, čtyřrozměrných atd. polí. V následujícím demonstračním příkladu je název třetí dimenze uložen v proměnné nazvané matrix.names:
> data <- 1:24 > dimension <- c(4, 3, 2) > > matrix.names <- c("matrix1", "matrix2") > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names, matrix.names)) > print(a1)
Při výpisu obsahu pole a1 se namísto indexů použijí všechny uvedené názvy, což vede k poněkud čitelnějším výstupům:
, , matrix1 column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12 , , matrix2 column1 column2 column3 row1 13 17 21 row2 14 18 22 row3 15 19 23 row4 16 20 24
9. Čtyřrozměrné pole
Jen pro úplnost si ukažme, jakým způsobem je možné zkonstruovat čtyřrozměrná pole. Základem bude vektor se dvaceti čtyřmi prvky, který je použit v konstruktoru:
data <- 1:24
Pole s tvarem 2×2×2×3 prvky:
> print("2x2x2x3") [1] "2x2x2x3" > dimension1 <- c(2, 2, 2, 3) > a1 <- array(data, dim=dimension1) > print(a1) , , 1, 1 [,1] [,2] [1,] 1 3 [2,] 2 4 , , 2, 1 [,1] [,2] [1,] 5 7 [2,] 6 8 , , 1, 2 [,1] [,2] [1,] 9 11 [2,] 10 12 , , 2, 2 [,1] [,2] [1,] 13 15 [2,] 14 16 , , 1, 3 [,1] [,2] [1,] 17 19 [2,] 18 20 , , 2, 3 [,1] [,2] [1,] 21 23 [2,] 22 24
Pole s tvarem 2×2×3×2 prvky:
> print("2x2x3x2") [1] "2x2x3x2" > dimension2 <- c(2, 2, 3, 2) > a2 <- array(data, dim=dimension2) > print(a2) , , 1, 1 [,1] [,2] [1,] 1 3 [2,] 2 4 , , 2, 1 [,1] [,2] [1,] 5 7 [2,] 6 8 , , 3, 1 [,1] [,2] [1,] 9 11 [2,] 10 12 , , 1, 2 [,1] [,2] [1,] 13 15 [2,] 14 16 , , 2, 2 [,1] [,2] [1,] 17 19 [2,] 18 20 , , 3, 2 [,1] [,2] [1,] 21 23 [2,] 22 24
Pole s tvarem 2×3×2×2 prvky:
> print("2x3x2x2") [1] "2x3x2x2" > dimension3 <- c(2, 3, 2, 2) > a3 <- array(data, dim=dimension3) > print(a3) , , 1, 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2, 1 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 , , 1, 2 [,1] [,2] [,3] [1,] 13 15 17 [2,] 14 16 18 , , 2, 2 [,1] [,2] [,3] [1,] 19 21 23 [2,] 20 22 24
Pole s tvarem 3×2×2×2 prvky:
> print("3x2x2x2") [1] "3x2x2x2" > dimension4 <- c(3, 2, 2, 2) > a4 <- array(data, dim=dimension4) > print(a4) , , 1, 1 [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 , , 2, 1 [,1] [,2] [1,] 7 10 [2,] 8 11 [3,] 9 12 , , 1, 2 [,1] [,2] [1,] 13 16 [2,] 14 17 [3,] 15 18 , , 2, 2 [,1] [,2] [1,] 19 22 [2,] 20 23 [3,] 21 24
Alternativně lze samozřejmě použít přiřazení vektoru s tvarem pole do výsledku funkce dim:
print("2x2x2x3") a1 <- 1:24 dimension1 <- c(2, 2, 2, 3) dim(a1) <- dimension1 print(a1) print("2x2x3x2") a2 <- 1:24 dimension2 <- c(2, 2, 3, 2) dim(a2) <- dimension2 print(a2) print("2x3x2x2") a3 <- 1:24 dimension3 <- c(2, 3, 2, 2) dim(a3) <- dimension3 print(a3) print("3x2x2x2") a4 <- 1:24 dimension4 <- c(3, 2, 2, 2) dim(a4) <- dimension4 print(a4)
10. Pojmenování třetí a čtvrté dimenze čtyřrozměrného pole
Pro úplnost si ještě uveďme, že pojmenovat lze nejenom řádky, sloupce a popř. celé submatice trojrozměrného pole, ale i větší prvky u polí s více dimenzemi:
> data <- 1:24 > > hypermatrix.names <- c("hypermatrix A", "hypermatrix B", "hypermatrix C") > matrix.names <- c("matrix1", "matrix2") > row.names <- c("row1", "row2") > column.names <- c("column1", "column2") > > print("2x2x2x3") [1] "2x2x2x3" > dimension <- c(2, 2, 2, 3) > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names, matrix.names, hypermatrix.names)) > print(a1) , , matrix1, hypermatrix A column1 column2 row1 1 3 row2 2 4 , , matrix2, hypermatrix A column1 column2 row1 5 7 row2 6 8 , , matrix1, hypermatrix B column1 column2 row1 9 11 row2 10 12 , , matrix2, hypermatrix B column1 column2 row1 13 15 row2 14 16 , , matrix1, hypermatrix C column1 column2 row1 17 19 row2 18 20 , , matrix2, hypermatrix C column1 column2 row1 21 23 row2 22 24
11. Přístup k prvkům dvojrozměrného pole
Připomeňme si, že programovací jazyk R umožňuje (pochopitelně) přístup k prvkům jednorozměrných vektorů. Indexy začínají od jedničky a zapisují se do hranatých závorek:
> v <- 1:12 > print(v[1]) [1] 1
Pokud se použije záporný index, vrátí se vektor, ovšem prvek s daným indexem (převedeným na absolutní hodnotu) je odfiltrován:
> v <- 1:12 > print(v[-1]) [1] 2 3 4 5 6 7 8 9 10 11 12
Vybrat je možné i větší množství prvků. V tomto případě se nepoužije index, ale vektor s indexy:
> v <- 1:12 > print(v[4:6]) [1] 4 5 6
Resp. obecněji:
> v <- 1:12 > print(v[c(2,4,6,8)]) [1] 2 4 6 8
Podobně můžeme přistupovat i k prvkům dvojrozměrných, trojrozměrných atd. polí. Indexy se zapisují do mezi jednu dvojici hranatých závorek a oddělují se od sebe čárkou – to je opět odlišné od některých „céčkovských“ jazyků, v nichž je každý index zapsán v samostatné dvojici závorek:
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12
Přečtení prvku z prvního řádku a prvního sloupce:
> print(a1[1, 1]) [1] 1
Přečtení prvků ze čtvrtého řádku:
> print(a1[4, 1]) [1] 4 > print(a1[4, 2]) [1] 8 > print(a1[4, 3]) [1] 12
12. Získání celého řádku dvojrozměrného pole
Zajímavé a dosti užitečné je, že pokud vynecháme jeden z indexů, vrátí se všechny prvky v dané dimenzi. To zní poměrně složitě, ovšem po pohledu na další demonstrační příklad bude celý koncept patrný:
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12
Zápisem a1[1,] (tedy druhý index chybí) se vrátí celý první řádek:
> print(a1[1,]) column1 column2 column3 1 5 9
Podobně můžeme přečíst celý druhý řádek atd.:
> print(a1[2,]) column1 column2 column3 2 6 10
13. Získání celého sloupce dvojrozměrného pole
Zajímavé je, že je podporován i opačný zápis, tj. vynechání prvního indexu namísto indexu druhého (resp. posledního):
a1[,1]
Podívejme se nyní na ucelený demonstrační příklad, ve kterém se vybírají celé sloupce. Povšimněte si, že i když se jedná o výběr sloupců, jsou vráceny ve formě jednorozměrného pole (popis řádků je však zachován):
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12 > print(a1[,1]) row1 row2 row3 row4 1 2 3 4 > > print(a1[,2]) row1 row2 row3 row4 5 6 7 8
14. Záporné indexy při přístupu k prvkům pole
Víme již, že při výběru prvku z vektoru lze použít záporný index. V takovém případě se vrátí vektor, ovšem prvek s daným indexem (převedeným na absolutní hodnotu) je odfiltrován:
> v <- 1:12 > print(v[-1]) [1] 2 3 4 5 6 7 8 9 10 11 12
Jak jsou však záporné indexy interpretovány u dvojrozměrných či vícerozměrných polí? Můžeme si to otestovat na dalším příkladu. Nejdříve pole zkonstruujeme a pro větší přehlednost pojmenujeme jeho řádky a sloupce:
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12
Nyní vybereme řádek s indexem –2 a druhý sloupec. Druhý sloupec obsahuje prvky 5, 6, 7 a 8, ovšem prvek 6 není vybrán, neboť leží na druhém řádku, který je odfiltrován. Výsledkem je tedy tříprvkový vektor:
> print(a1[-2, 2]) row1 row3 row4 5 7 8
Podobně můžeme vybrat druhý řádek, tedy prvky 2, 6 a 10 a všechny sloupce kromě druhého (tím nám z vektoru vypadne prvek s hodnotou 6):
> print(a1[2, -2]) column1 column3 2 10
A konečně při použití dvojice indexů –2, –2 se vybere původní pole, ovšem bez druhého sloupce a současně i bez druhého řádku:
> print(a1[-2, -2]) column1 column3 row1 1 9 row3 3 11 row4 4 12
Podobně můžeme postupovat i u vícerozměrných polí:
a1 <- 1:24 dimension1 <- c(2, 3, 4) dim(a1) <- dimension1 print(a1) print("----------") print(a1[-1, 1, 1]) print("----------") print(a1[1, -1, 1]) print("----------") print(a1[-1, 1, -1])
S výsledky:
, , 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12 , , 3 [,1] [,2] [,3] [1,] 13 15 17 [2,] 14 16 18 , , 4 [,1] [,2] [,3] [1,] 19 21 23 [2,] 20 22 24 [1] "----------" [1] 2 [1] "----------" [1] 3 5 [1] "----------" [1] 8 14 20
15. Filtrace řádků při výběru s využitím záporných indexů
Nyní můžeme zkombinovat dvě výběrové techniky popsané v předchozích kapitolách:
- Výběr celých řádků tím, že se vynechá index sloupce.
- Filtrace řádků s určitým indexem v případě, že se použije záporný index.
Podívejme se na kód demonstračního příkladu. Nejdříve se zkonstruuje dvojrozměrné pole:
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12
Výběr všech řádků kromě prvního:
> print(a1[-1, ]) column1 column2 column3 row2 2 6 10 row3 3 7 11 row4 4 8 12
Výběr všech řádků kromě druhého:
> print(a1[-2, ]) column1 column2 column3 row1 1 5 9 row3 3 7 11 row4 4 8 12
Výběr všech řádků kromě třetího:
> print(a1[-3, ]) column1 column2 column3 row1 1 5 9 row2 2 6 10 row4 4 8 12
Řádky, které se mají vybírat, mohou být reprezentovány vektorem:
data <- 1:12 dimension <- c(4, 3) row.names <- c("row1", "row2", "row3", "row4") column.names <- c("column1", "column2", "column3") a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) print(a1[c(4,1), ])
S výsledkem:
column1 column2 column3 row4 4 8 12 row1 1 5 9
16. Filtrace sloupců při výběru s využitím záporných indexů
Logicky bude následovat podobný demonstrační příklad, ovšem s filtrací sloupců. V tomto příkladu se z původního dvojrozměrného pole získá nové pole, které bude mít shodný počet řádků s polem zdrojovým, ovšem sloupce budou filtrovány (vždy bude jeden z nich vynechán):
> data <- 1:12 > dimension <- c(4, 3) > > row.names <- c("row1", "row2", "row3", "row4") > column.names <- c("column1", "column2", "column3") > > a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) > > print(a1) column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12 > print(a1[, -1]) column2 column3 row1 5 9 row2 6 10 row3 7 11 row4 8 12 > print(a1[, -2]) column1 column3 row1 1 9 row2 2 10 row3 3 11 row4 4 12 > print(a1[, -3]) column1 column2 row1 1 5 row2 2 6 row3 3 7 row4 4 8
Výběr konkrétních sloupců s využitím výběrového vektoru:
data <- 1:12 dimension <- c(4, 3) row.names <- c("row1", "row2", "row3", "row4") column.names <- c("column1", "column2", "column3") a1 <- array(data, dim=dimension, dimnames=list(row.names, column.names)) print(a1) print(a1[, c(3,2,1)]) print(a1[, c(3,1)]) print(a1[, c(1,1,1,1)])
S výsledky:
column1 column2 column3 row1 1 5 9 row2 2 6 10 row3 3 7 11 row4 4 8 12 column3 column2 column1 row1 9 5 1 row2 10 6 2 row3 11 7 3 row4 12 8 4 column3 column1 row1 9 1 row2 10 2 row3 11 3 row4 12 4 column1 column1 column1 column1 row1 1 1 1 1 row2 2 2 2 2 row3 3 3 3 3 row4 4 4 4 4
17. Operace provedená nad korespondujícími prvky dvou polí
Na dvojici polí lze aplikovat běžné aritmetické operátory. Ty jsou vždy aplikovány na korespondující prvky polí, operace se tedy provádí prvek po prvku. Příkladem může být „součet polí“, který vlastně v případě dvojrozměrných polí odpovídá součtu matic:
> data1 <- c(1, 2, 3, 4, 5, 6) > data2 <- -6:-1 > > dimension <- c(3, 2) > > a1 <- array(data1, dim=dimension) > print(a1) [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 > > a2 <- array(data2, dim=dimension) > print(a2) [,1] [,2] [1,] -6 -3 [2,] -5 -2 [3,] -4 -1 > > print(a1 + a2) [,1] [,2] [1,] -5 1 [2,] -3 3 [3,] -1 5
Pole ovšem musí mít stejné rozměry (stejný tvar):
data1 <- c(1, 2, 3, 4, 5, 6) data2 <- -6:-1 dimension1 <- c(3, 2) a1 <- array(data1, dim=dimension1) print(a1) dimension2 <- c(2, 3) a2 <- array(data2, dim=dimension2) print(a2) print(a1 + a2)
Pokus o spuštění tohoto příkladu skončí s chybou:
[,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 [,1] [,2] [,3] [1,] -6 -4 -2 [2,] -5 -3 -1 Error in a1 + a2 : non-conformable arrays Calls: print Execution halted
I dělení se provádí prvek po prvky, nejedná se tedy o pokus o dělení matic (tedy výpočet inverzní matice a vynásobení první matice s inverzí matice druhé):
> data1 <- c(1, 2, 3, 4, 5, 6) > data2 <- -6:-1 > > dimension <- c(3, 2) > > a1 <- array(data1, dim=dimension) > print(a1) [,1] [,2] [1,] 1 4 [2,] 2 5 [3,] 3 6 > > a2 <- array(data2, dim=dimension) > print(a2) [,1] [,2] [1,] -6 -3 [2,] -5 -2 [3,] -4 -1 > > print(a1 / a2) [,1] [,2] [1,] -0.1666667 -1.333333 [2,] -0.4000000 -2.500000 [3,] -0.7500000 -6.000000
18. Od dvojrozměrných polí k maticím
V předchozím textu jsme se bavili převážně o polích – jednorozměrných, dvojrozměrných i vícerozměrných. U dvojrozměrných polí jsem se snažil vynechat označení „matice“, a to z toho důvodu, že matice (matrix) jsou v programovacím jazyku R samostatným datovým typem odlišným od polí. A skutečně – mezi poli a maticemi je několik rozdílů:
# | Pole | Matice |
---|---|---|
1 | typ array | typ matrix |
2 | 1, 2, 3 … N dimenzí | striktně dvě dimenze (2D struktura) |
3 | homogenní typ | homogenní typ |
4 | založeno na jediném vektoru s info o dimenzích | složeno ze sady vektorů shodné délky |
5 | používáno primárně pro uložení dat | používáno primárně pro transformaci dat |
6 | relativně malé množství operací | plná sada „maticových“ operací |
7 | nadmnožina nad maticemi | speciální případ pole se dvěma dimenzemi |
8 | konstruktor array | konstruktor matrix |
Matice si podrobně popíšeme příště, ovšem již nyní si můžeme ukázat způsob jejich konstrukce. Pro vytvoření matice se používá konstruktor nazvaný matrix, kterému se předá vektor s daty (hodnotami prvků), počet řádků a počet sloupců (popř. obráceně):
> data <- 1:12 > > m1 <- matrix(data, nrow=1, ncol=12) > print(m1) [,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 > > m2 <- matrix(data, nrow=2, ncol=6) > print(m2) [,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 3 5 7 9 11 [2,] 2 4 6 8 10 12 > > m3 <- matrix(data, nrow=3, ncol=4) > print(m3) [,1] [,2] [,3] [,4] [1,] 1 4 7 10 [2,] 2 5 8 11 [3,] 3 6 9 12 > > m4 <- matrix(data, nrow=4, ncol=3) > print(m4) [,1] [,2] [,3] [1,] 1 5 9 [2,] 2 6 10 [3,] 3 7 11 [4,] 4 8 12 > > m5 <- matrix(data, nrow=6, ncol=2) > print(m5) [,1] [,2] [1,] 1 7 [2,] 2 8 [3,] 3 9 [4,] 4 10 [5,] 5 11 [6,] 6 12 > > m6 <- matrix(data, nrow=12, ncol=1) > print(m6) [,1] [1,] 1 [2,] 2 [3,] 3 [4,] 4 [5,] 5 [6,] 6 [7,] 7 [8,] 8 [9,] 9 [10,] 10 [11,] 11 [12,] 12
Opět můžeme využít toho, že pokud je vektor se zdrojovými daty kratší, než vyžaduje konstrukce matice, je postupně prodlužován. Takto se například vytvoří nulová matice:
zero <- 0 m1 <- matrix(zero, nrow=10, ncol=10) print(m1)
S výsledky:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] 0 0 0 0 0 0 0 0 0 0 [2,] 0 0 0 0 0 0 0 0 0 0 [3,] 0 0 0 0 0 0 0 0 0 0 [4,] 0 0 0 0 0 0 0 0 0 0 [5,] 0 0 0 0 0 0 0 0 0 0 [6,] 0 0 0 0 0 0 0 0 0 0 [7,] 0 0 0 0 0 0 0 0 0 0 [8,] 0 0 0 0 0 0 0 0 0 0 [9,] 0 0 0 0 0 0 0 0 0 0 [10,] 0 0 0 0 0 0 0 0 0 0
Podrobnější informace o způsobech využití matic si popíšeme v navazující části tohoto seriálu.
19. Repositář s demonstračními příklady
Zdrojové kódy všech dnes použitých demonstračních příkladů byly uloženy do nového Git repositáře, který je dostupný na adrese https://github.com/tisnik/r-examples V případě, že z nějakého důvodu nebudete chtít klonovat celý repositář (ten je ovšem – alespoň prozatím – velmi malý, dnes má stále jen jednotky kilobajtů), můžete namísto toho použít odkazy na jednotlivé demonstrační příklady, které naleznete v následující tabulce:
20. Odkazy na Internetu
- The R Project for Statistical Computing
https://www.r-project.org/ - An Introduction to R
https://cran.r-project.org/doc/manuals/r-release/R-intro.pdf - R (programming language)
https://en.wikipedia.org/wiki/R_(programming_language) - The R Programming Language
https://www.tiobe.com/tiobe-index/r/ - R Markdown
https://rmarkdown.rstudio.com/ - R Markdown: The Definitive Guide
https://bookdown.org/yihui/rmarkdown/ - R Markdown Cheat Sheet
https://rstudio.com/wp-content/uploads/2016/03/rmarkdown-cheatsheet-2.0.pdf - Introduction to R Markdown
https://rmarkdown.rstudio.com/articles_intro.html - R Cheat Sheets
https://blog.sergiouri.be/2016/07/r-cheat-sheets.html - R Cheat Sheet
https://s3.amazonaws.com/quandl-static-content/Documents/Quandl±+R+Cheat+Sheet.pdf - Base R Cheat Sheet
https://rstudio.com/wp-content/uploads/2016/06/r-cheat-sheet.pdf - PYPL PopularitY of Programming Language
https://pypl.github.io/PYPL.html - Tiobe index
https://www.tiobe.com/tiobe-index/ - Stack Overflow: Most Loved, Dreaded & Wanted Programming Languages In 2020
https://fossbytes.com/stack-overflow-most-loved-dreaded-wanted-programming-languages-in-2020/ - How to Install and Use R on Ubuntu
https://itsfoss.com/install-r-ubuntu/ - R programming for beginners – Why you should use R
https://www.youtube.com/watch?v=9kYUGMg_14s - GOTO 2012 • The R Language The Good The Bad & The Ugly
https://www.youtube.com/watch?v=6S9r_YbqHy8 - R vs Python – What should I learn in 2020? | R and Python Comparison
https://www.youtube.com/watch?v=eRP_J2yLjSU - R Programming 101
https://www.youtube.com/c/rprogramming101 - Seriál Tvorba grafů pomocí programu „R“
https://www.root.cz/serialy/tvorba-grafu-pomoci-programu-r/ - Tvorba grafů pomocí programu „R“: úvod
https://www.root.cz/clanky/tvorba-grafu-pomoci-programu-r-1/ - Tvorba grafů pomocí programu „R“: pokročilé funkce
https://www.root.cz/clanky/tvorba-grafu-pomoci-programu-r-pokrocile-funkce/ - Tvorba grafů pomocí programu „R“: vkládání textu, čeština
https://www.root.cz/clanky/grafy-pomoci-programu-r-vkladani-textu-cestina/ - Cesta erka: Krok nultý – instalace & nastavení – prostředí, projekty, package
https://www.jla-data.net/r4su/r4su-environment-setup/ - Cesta erka: Krok první – operace a struktury – proměnné, rovnítka a dolary
https://www.jla-data.net/r4su/r4su-data-structures/ - Cesta erka: Krok druhý – načtení externích dat – csvčka, excely a databáze
https://www.jla-data.net/r4su/r4su-read-data/ - Cesta erka: Krok třetí – manipulace s daty – dplyr, slovesa a pajpy
https://www.jla-data.net/r4su/r4su-manipulate-data/ - Cesta erka: Krok čtvrtý – podání výsledků – ggplot, geomy a estetiky
https://www.jla-data.net/r4su/r4su-report-results/ - Cesta erka: Krok pátý – case study – případ piva v Praze
https://www.jla-data.net/r4su/r4su-case-study-beer/ - V indexu popularity programovacích jazyků TIOBE překvapilo R, Go, Perl, Scratch a Rust
https://www.root.cz/zpravicky/v-indexu-popularity-programovacich-jazyku-tiobe-prekvapilo-r-go-perl-scratch-a-rust/ - Is R Programming SURGING in Popularity in 2020?
https://www.youtube.com/watch?v=Duwn-vImyXE - Using the R programming language in Jupyter Notebook
https://docs.anaconda.com/anaconda/navigator/tutorials/r-lang/ - Using R on Jupyter Notebook
https://dzone.com/articles/using-r-on-jupyternbspnotebook - Graphics, ggplot2
http://r4stats.com/examples/graphics-ggplot2/ - A Practice Data Set
https://r4stats.wordpress.com/examples/mydata/ - Shiny – galerie projektů
https://shiny.rstudio.com/gallery/ - Seriál Programovací jazyk Julia
https://www.root.cz/serialy/programovaci-jazyk-julia/ - Julia (front page)
http://julialang.org/ - Julia – repositář na GitHubu
https://github.com/JuliaLang/julia - Julia (programming language)
https://en.wikipedia.org/wiki/Julia_%28programming_language%29 - IJulia
https://github.com/JuliaLang/IJulia.jl - Introducing Julia
https://en.wikibooks.org/wiki/Introducing_Julia - Julia: the REPL
https://en.wikibooks.org/wiki/Introducing_Julia/The_REPL - Introducing Julia/Metaprogramming
https://en.wikibooks.org/wiki/Introducing_Julia/Metaprogramming - Month of Julia
https://github.com/DataWookie/MonthOfJulia - Learn X in Y minutes (where X=Julia)
https://learnxinyminutes.com/docs/julia/ - New Julia language seeks to be the C for scientists
http://www.infoworld.com/article/2616709/application-development/new-julia-language-seeks-to-be-the-c-for-scientists.html - Julia: A Fast Dynamic Language for Technical Computing
http://karpinski.org/publications/2012/julia-a-fast-dynamic-language - The LLVM Compiler Infrastructure
http://llvm.org/ - Julia: benchmarks
http://julialang.org/benchmarks/ - R Vector
https://www.datamentor.io/r-programming/vector/ - .R File Extension
https://fileinfo.com/extension/r - Lineární regrese
https://cs.wikipedia.org/wiki/Line%C3%A1rn%C3%AD_regrese - lm (funkce)
https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/lm - quit (funkce)
https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/quit - c (funkce)
https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/c - help (funkce)
https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/help - Shiny: Introduction to interactive documents
https://shiny.rstudio.com/articles/interactive-docs.html - R Release History 1997–2013
http://timelyportfolio.github.io/rCharts_timeline_r/ - R: atomic vectors
https://renenyffenegger.ch/notes/development/languages/R/data-structures/vector/ - 11 Best R Programming IDE and editors
https://www.dunebook.com/best-r-programming-ide/ - CRAN – The Comprehensive R Archive Network
https://cran.r-project.org/ - R – Arrays
https://www.tutorialspoint.com/r/r_arrays.htm - Array vs Matrix in R Programming
https://www.geeksforgeeks.org/array-vs-matrix-in-r-programming/?ref=rp - Online R Language IDE
https://www.jdoodle.com/execute-r-online/ - Execute R Online (R v3.4.1)
https://www.tutorialspoint.com/execute_r_online.php - Snippets: Run any R code you like. There are over twelve thousand R packages preloaded
https://rdrr.io/snippets/ - R Package Documentation
https://rdrr.io/