4  Opakovaní R

Cíle cvičení
  • Umět vyhledat nápovědu k funkci.
  • Ovládat základní matematické výpočty pmocí funkcí a operátorů.
  • Umět definovat objekt v datovém typy a struktuře a tyto vzájemně transoformovat.
  • Ovládat běh výpočtu pomocí podmínek a cyků.
  • Přidávat k pracovnímu postupu vlastní funkce.

Základy jazyka jsou vyučovány již v prvním semestru studia Vodního hospodářství. Na tomto místě je pouze zhuštěný přehled funkcionality z uvedeného kurzu.

4.1 Nápověda

Zadává se do konzole ve tvaru help(<jméno funkce>), nebo <jmeno funkce>. Pokud bychom se chtěli podívat přímo do kódu funkce, také je to možné, jméno funkce pouze vepíšeme do konzole bez závorek, případně použijeme příkazu View(<jmeno funkce>). Kromě toho existuje v R také help.search(<jméno funkce>) pod zkratkou ??, jež hledá fulltextovou nápovědu napříč nainstalovanými balíčky. Dále je ještě možné prohledat mailing list jazyka R pomocí funkce RSiteSearch(), která otevře nové okno předdefinovaného prohlížeče. Dále jsou velmi užitečné tematicky ucelené karty nápověd: ?Logical, ?Constants, ?Control, ?Arithmetic, ?Syntax, ?Special a další.

Úloha
  1. Vyhledejte nápovědu k DateTimeClasses.
    1. Co reprezentují třídy POSIXct a POSIXlt?
    2. Jaký je mezi nimi rozdíl?
    3. Nalezněte funkci pro výpočet \(5!\)

4.2 Jmenné konvence

Objekty, které vznikají při práci s R musí splňovat následující jmenné konvence. Název objektu nelze začínat číslovkou nebo operátorem, nesmít být totžný s žádným klíčovým slovem, obsahovat mezeru.

Klíčová slova

if, else, repeat, while, function, for, in, next, repeat, break, TRUE, FALSE, NULL, Inf, NaN, NA, NA_integer_, NA_real_, NA_complex_, NA_character_, a speciální znak: _

Nedoporučuje se vkládat do názvu proměnné tečku, např. morava.prutoky, a pojmenovávat shodně s běžně používanou funkcí. R je “case-sensitive” jazyk tzn., že proměnná X se nerovná x.

Úloha
  1. Intuitivně by nás mohlo vést nahrát data do proměnné data. Je to chybný postup, neboť data() je funkce zpřístupňující datové sady, kterou jsou součástí instalace. Vyzkoušejte.
Příklady nevhodných proměnných

aaa, Morávka průtok [m/s], moje.proměnná
Žádné z těchto jmen proměnných není proti

4.3 Uvozovky a závorky

Představují párové znaky jazyka R. Závorky se používají trojího typu: kulaté, hranaté a složené a všechny mají jasně vymezné pole působnosti.

  • () se používají vždy se jménem funkce a uvozují prostor ve kterém se parametrizují argumenty funkce.
  • [] se vždy pojí se jménem objektu (vektoru, pole, listu, …) a vymezují výběr z daného objektu.
  • {} ohraničují blok kódu, který se má vykonat v celku.

Uvozovky uvozují textové řetězce. Lze používat jak dvojté " tak jednoduché ' uvozovky zcela zástupně, je pouze třeba uzavírat shodným typem. Hojně se lze setkat se zpětnými uvozovkami, které se například použijí pro ohraničení nestandardního názvu sloupce ve struktuře.

Kód
"Správně"
"Špatně'
Úloha
  1. Zadejte špatnou variantu z kódu výše do konzole a sledujte chování prostředí. Co vyjadřuje znak +?

4.4 Operátory

Rozlišujeme operátory aritmetické, relační, přiřazení a patří sem i množinové funkce.

Znak Význam
+ , - , * , / , %% , %/% , ** nebo ^, %*% aritmetické operátory (sčítání, odčítání, násobení, dělení, modulo, celočíselné dělení, mocnění a maticové násobení)
> ,>= , < , <= , == , != relační operátory (větší/menžší než, rovno, nerovno)
! , & , && , | , || logické (ne, a soužasně, zdvojené po prvcích vektoru)
~ zadání funkčního vztahu
<- , =, <<-, -> operátory přiřazení
$ jmenný index v heterogenních strukturách
: rozsah
isTRUE() , all() , any() , %in% , setdiff() množinové funkce
Kód

xor(x)
isTRUE(x)
any()
all()
%in%
setdiff(x, y)
11
Negace
12
Je \(x\) “pravda”?
13
Je něco z obsahu “pravda”?
14
Je vše z obsahu “pravda”?
15
Je něco obsaženo v?
16
Chybí něco něco z obsahu v?
Úloha
  1. Použite k výpočtu operátory či množinové funkce:
    1. Zjistěte, zda je číslo 1109388 dělitelné 7.
    2. Do vektoru \(\mathbf{\mathrm{a}}\) uložte násobky 3 v rozsahu \(\langle-121;30\rangle\) a \(\mathbf{\mathrm{b}}\) násobky 7 v rozmezí
    3. Vypište hodnoty

4.5 Matematické funkce

Funkce Význam
log(x) logaritmus \(x\) o základu \(e\)
exp(x) odlogaritmování \(x(e^x)\)
log(x, n) logaritmus \(x\) o základu \(n\)
log10(x) logaritmus \(x\) o základu \(10\)
sqrt(x) druhá odmocnina z \(x\)
factorial(x) \(x!\)
choose(n, x) binomické koeficienty \[ \binom{n}{k} = \frac{n!}{k!(n-k)!} \]
ceiling(x) nejmenší celé číslo větší než \(x\)
floor(x) největší celé číslo před \(x\)
trunc(x) nejbliřší celé číslo mez i\(x\) a 0
round(x, digits) zaokrouhlení \(x\) na \(n\) desetinných míst
signif(x, digits) zaokrouhlení na počet platných číslic
cos(x) , sin(x) , tan(x) funkce kosinus, sinus, tangens v radianech
acos(x) , asin(x) , atan(x) inverzní trigonometrické funkce
abs(x) absolutní hodnota
Úloha
  1. Vyhodnoťte s pomocí R následující výrazy:
    1. \(1 + 3 \cdot (2 / 3)\:\mathrm{mod}\:3=\)
    2. \(\dfrac{\sin(2.3)}{\cos(\pi)}=\)
    3. \(\sum\limits_{i = 1}^{53}i=\)
    4. \(\dfrac{-\infty}{0}=\) , \(\dfrac{-\infty}{\infty}=\) , \(\dfrac{0}{0}=\)
    5. \(\left(\dfrac{2}{35}\right)^{0.5} \cdot 3 \cdot (2 / 3)=\)
    6. \(20!=\)
    7. \(\int_{0}^{3\pi} \sin(x) dx=\)
    8. \(\sqrt[3]{561}=\)
    9. \(\mathrm{diag}\left( \pmatrix{5\\ 3}\cdot \pmatrix{6 & 5}\right)=\)
    10. \(y=x^2 + 3\sqrt{x};\:y^\prime=\)

4.6 Datové typy

Tvoří prvky struktur. R je dynamicky typovaný jazyk, nepožaduje před zavedením proměnné její deklaraci.

Základní datové typy a nucené převody mezi nimi.
logical integer numeric complex character
logical logical integer numeric complex character
integer logical integer numeric complex character
numeric logical numeric numeric complex character
complex logical integer + warning numeric + warning complex character
character NA_logical NA_integer + warning NA_numeric + warning NA_complex + warning character

K datovým typům (třídám) se pojí funkce is.___ a as.___ kteří slouží k dotazování na typ, resp. jeho nucenou změnu a dále funkce class(), mode() .

Kód
is.character("ABC")
[1] TRUE
Kód
as.integer(11 + 1i)
Warning: imaginary parts discarded in coercion
[1] 11

Chybějící záznamy a speciální numerické případy NA, NaN, NULL, Inf, -Inf jsou hodnoty, které mohou vzniknout například jako výsledek početního úkonu, nebo špatného importu dat. Výraz NA je tvořen v datovém typu logical, nejméně náročném na paměť. Jinak je možné specifikovat chybějící hodnotu ve všech ostatních datových typech NA_real_ (odpovídá double), NA_integer_, NA_complex_ a NA_character_, které je vhodné využít zejména při vytváření datového rámce s přesně zadaným typem sloupců. NULL je návratová hodnota mnoha funkcí a výrazů, reprezentuje prázdný objekt. Výsledky NaN a ±Inf pochází z aritmetických operací \(\dfrac{1}{0}\) resp. \(\dfrac{\pm0}{1}\) . na.omit(), is.na(), complete.cases().

4.7 Základní datové struktury

Základní datové struktury rozlišujeme na atomické (homogenní) a heterogenní datové struktury.

4.7.1 Homogenní datové struktury

Homogenní datové struktury obsahují atomické vektory, faktory, matice a pole. Název je odvozen od jejich omezení v podvýběru obsahovat pouze typ sebe sama tzn. podvýběr matice může být opět pouze matice.

4.7.1.1 Atomický vektor vector

Vektor je v jazyce R základní stavební strukturou, nic jaká skalární veličina zde není. Koncept vektoru je zde chápán v matematickém smyslu jako jednosloupcová matice \(\boldsymbol{\mathrm{A}} = (a_{ij})_{m1}\) hodnot.

\[ \mathbf{\mathrm{u}} = \begin{pmatrix} 1\\ 1.5\\ -14\\ 7.223\\ \end{pmatrix}, \qquad \mathbf{\mathrm{v}} = \begin{pmatrix} \mathrm{TRUE}\\ \mathrm{FALSE}\\ \mathrm{TRUE}\\ \mathrm{TRUE}\\ \end{pmatrix}, \qquad \mathbf{\mathrm{u^T}} = \begin{pmatrix} 1 & 1.5 & -14 & 7.233\\ \end{pmatrix} \]

Může nabývat jakéhokoliv datového typu, nicméně všechny prvky v daném vektoru jsou právě jednoho typu, čímž rozumíme, že je tato struktura tzv. homogenní. Vektor je možné vytvořit mnoha způsoby, mezi nejčastější patří funkce vector(mode = "numeric", length = 10) a funkce c(), případně vzniká pomocí opetárorů [ nebo [[.

S vektory se pojí důležité pravidlo - recyklace hodnot.

Kód
v <- c(1.4, 2.0, 6.1, 2.7)
u <- c(2.0, 1.3)
u + v
u * v
u * 2.3
1
Sčítám vektory přičemž délka jednoho je násobkem délky druhého.
2
Násobím vektory přičemž délka jednoho je násobkem délky druhého.
3
Násobení vektoru číslenou hodnotou
[1] 3.4 3.3 8.1 4.0
[1]  2.80  2.60 12.20  3.51
[1] 4.60 2.99
Práce s vektory
Kód
x <- 1:10
x <- seq(10:1)
x <- vector(mode = "numeric", length = 10)
x <- replicate(n = 10, expr = eval(2))
x <- sample(x = 10, size = 10, replace = TRUE)
x <- rep(x = 15, times = 2)
x <- rnorm(n = 10, mean = 2, sd = 20)
t(x) * x
names(x) <- LETTERS[1:length(x)]
x[x > 0]
x[1:3]
1
Tvorba vektoru \(\boldsymbol{\mathrm{x}}\) různými úkony. Použití sekvence, repetice, opakování a vzorkování.
2
Transpozice vektoru.
3
Pojmenování pozic ve vektoru
4
Výběr hodnot z vektoru na základě podmínky
5
Výběr hodnot z vektoru na základě pozice
         [,1]     [,2]     [,3]     [,4]     [,5]       [,6]     [,7]     [,8]
[1,] 418.2779 46.00991 898.1805 66.07044 161.6351 0.08361656 79.08682 24.76843
         [,9]    [,10]
[1,] 257.3706 1230.501
         A          F          H          I          J 
20.4518433  0.2891653  4.9767891 16.0427731 35.0784996 
         A          B          C 
 20.451843  -6.783061 -29.969659 
Úloha
    1. Vytvořte libovolným způsobem vektor x 10 různých číselných hodnot, kde \(x\in\mathbb{R}\).
    2. Zapište výraz pro výběr čísel v rozmezí -5 a 5 z tohoto vektoru.
    3. Proveďte převod na celočíselný typ a diskutujte výsledek.
    4. Přidejte k vektoru 3 pozice “A”, “B” a “C”, změnil se vektor?

4.7.1.2 Faktor

Faktorem rozumíme kategorickou proměnnou, která je určena výčtem hodnot. Ukážeme si na příkladu “tříd přesnosti měření”.

Kód
trida <- factor(x = 1:4,
                labels = c(paste(1:4, ". třída", sep = "")), 
                ordered = TRUE)

4.7.1.3 Matice matrix

Rozšířením rozměrů vektoru vznikne matice nebo obecně pole.

Kód
x <- c(1:10)
dim(x) <- c(2, 5)
x
1
Převod na rozměr \(2\times 2\)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    3    5    7    9
[2,]    2    4    6    8   10
Funkce Úkon
nrow(), ncol() počet řádků, sloupců matice
dim() řádky \(\times\) sloupce matice
det() deteminant matice
eigen() vlastní čísla a vlastní vektory matice
colnames() jména sloupců v matici
rowSums() řádkové součty matice
colMeans() sloupcové průměry matice
M[m, ] Výběr \(m\)-tého řádku matice
M[ ,n] Výběr \(n\)-tého sloupce matice

Stejně jako u vektoru opět platí typová homogenita

Kód
B <- matrix(
  data = c(1, 2 + 3i, 5.4, 4, 5), 
  nrow = 2, 
  ncol = 3)
Warning in matrix(data = c(1, 2 + (0+3i), 5.4, 4, 5), nrow = 2, ncol = 3): data
length [5] is not a sub-multiple or multiple of the number of rows [2]
Kód
A <- matrix(data = seq(from = 1, to = 16, by = 2), nrow = 4)
str(A)
dim(A)
svd(A)
diag(A)
# sweep(x = A, MARGIN = 1, STATS = mean)
##  num [1:4, 1:2] 1 3 5 7 9 11 13 15
## [1] 4 2
## $d
## [1] 25.930394  2.759471
## 
## $u
##            [,1]       [,2]
## [1,] -0.3396065 -0.7646355
## [2,] -0.4383147 -0.3284512
## [3,] -0.5370229  0.1077330
## [4,] -0.6357311  0.5439173
## 
## $v
##            [,1]       [,2]
## [1,] -0.3389761  0.9407950
## [2,] -0.9407950 -0.3389761
## 
## [1]  1 11
1
Struktura objektu
2
Dimenze matice
3
Singulární rozklad
4
Prvky na diagonále matice
Úloha
    1. S pomocí nápovědy k funkci rnorm() vytvořte matici \(\boldsymbol{\mathrm{M}}; h(\boldsymbol{\mathrm{M}}) = 8\) náhodných čísel.
    2. Vytvořte vektor hodnot od \(100\) do \(1\) sestupně, využijte nápovědu k funkci seq().
    3. Spočtěte rozdíl, matic \(\boldsymbol{\mathrm{A}}\), \(\boldsymbol{\mathrm{B}}\). \[\boldsymbol{\mathrm{A}} = \left( \begin{matrix} 2 & 2 & 5\\ 9 & 2 & 7\\ 1 & 3 & 18\\ \end{matrix} \right),\qquad \boldsymbol{\mathrm{B}} = \left( \begin{matrix} 5 & 4 & 5\\ -7 & 2 & 4\\ 10 & 1 & 5\\ \end{matrix} \right) \]
    4. Spočítejte inverzní matici k matici \(\boldsymbol{\mathrm{A}}\). Najděte vhodnou funkci s pomocí nápovědy.
    5. S pomocí hodnot TRUE/FALSE vytvořte matici \(\boldsymbol{\mathrm{M}}(3,3)\), změňte typ prvku na pozici \(\boldsymbol{\mathrm{M}}[1, 1]\) na textový řetězec. Ovlivní tato změna ostatní prvky v matici?
    6. Vyřešte s pomocí R soustavu lineárních rovnic: \[\begin{array} -3x & +2y& +z&=1\\ -2x & -y& +z&=2\\ 2x & +y& -4z&=0 \end{array} \]

4.7.2 Heterogenní datové struktury

Za rúznorodé struktury se označují ty, které mohou uchovávat dva a více prvků rozdílného typu současně. Z těch základních to jsou data.frame a list, dále pak S4, nebo R6 třídy, případně další uživatelem vytvořené struktury.

4.7.2.1 Datová tabulka data.frame

data.frame je de facto vektor stejně dlouhých vektorů, které kromě toho, že musí být shodné délky, mohou být vzájmeně rozdílného datového typu.

Kód
DF <- data.frame(name = letters[1:5], 
                 value = rnorm(5))
DF
##   name       value
## 1    a  1.12780592
## 2    b  0.40404050
## 3    c  0.19324584
## 4    d -0.95829378
## 5    e  0.04486513
DF["name"]        # podvýběr do data.frame
##   name
## 1    a
## 2    b
## 3    c
## 4    d
## 5    e
DF[["name"]]      # podvýběr do vektoru
## [1] "a" "b" "c" "d" "e"
DF[, "name"]      # podvýběr do vektoru
## [1] "a" "b" "c" "d" "e"

Práce uvnitř data.frame

Kód
DF <- data.frame(
  mon = rep(month.abb, 
            times = c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)), 
  value = rnorm(365), 
  yr = 2001)
str(DF)
## 'data.frame':    365 obs. of  3 variables:
##  $ mon  : chr  "Jan" "Jan" "Jan" "Jan" ...
##  $ value: num  1.0997 -0.7848 -0.0111 -0.4826 -0.6116 ...
##  $ yr   : num  2001 2001 2001 2001 2001 ...
names(DF)
## [1] "mon"   "value" "yr"
nrow(DF)
## [1] 365
ncol(DF)
## [1] 3

4.8 Řídící struktury

Zajišťují obecný průběh programu, tvoří základní prvky algoritmů. Mezi řídící strukury řadíme podmínky a cykly. Mohli bychom přidat i složené závorky, něboť pro struktury uvozují bloky kódu.

4.8.1 Podmínky

4.8.1.1 if()

Kód
A <- 1
if(A >= 1) {
  cat("A je větší nebo shodné s 1.")
}
A je větší nebo shodné s 1.
Kód
A <- 5
if(A >= 2) {
  cat("A je větší nebo shodné s 2.")
} else if(A > 2) {
  cat("A je větší než 2.")
}
1
Řetěz podmínek se uzavře v momentě, kdy je výraz v závorce poprvé vyhodnocen jako pravdivý.
A je větší nebo shodné s 2.

4.8.1.2 ifelse()

Vektorizovaný tvar podmínky, který lze volat na prvky struktur.

Kód
x <- -5:5
cat("Prvek x + 3 je více než 0: ", ifelse(x - 3 > 0, yes = "Ano", no = "Ne"))
Prvek x + 3 je více než 0:  Ne Ne Ne Ne Ne Ne Ne Ne Ne Ano Ano

4.8.1.3 switch()

Kód
varianta <- "B"
2 * (switch(
      varianta,
        "A" = 2,
        "B" = 3))
1
Varianta “A nenastala,
2
nastala varianta “B”, tzn. výraz je vyhodnocen ve tvaru \(2\cdot 3 = 6\)
[1] 6
Úloha
    1. Vytvořte s pomocí podmínek známkovací schéma:
Známka Rozmezí
1 90 - 100 %
2 75 - 89 %
3 60 - 74 %
4 < 60 %

4.8.2 Cykly

Zajištují, že se část kódu provede opakovaně.

4.8.2.1 for() z definovaného rozsahu

Pokud je předem znám počet opakování cyklu (nebo je i jinak implicitně určen), používá se for cyklu.

Kód
for(i in 1:4) {
  cat("Iterace ", i, "\n")
}
Iterace  1 
Iterace  2 
Iterace  3 
Iterace  4 

4.8.2.2 while() s pomocí podmínky

V případech, kdy počet opakování není předem znám, ale je známa podmínka, za které cyklus má probíhat.

Kód
i <- 1
while(i < 5) {
  cat("Iterace ", i, "\n")
  i <- i + 1
}
Iterace  1 
Iterace  2 
Iterace  3 
Iterace  4 

4.8.2.3 repeat s únikovou sekvencí

Počet opakování neni předem znám. Nicméně lze definovat případ, kdy má cyklus skončit.

Kód
i <- 1
repeat {
  cat("Iterace ", i, "\n")
  i <- i + 1
  if(i >= 5) break #<1>
}
1
Prováděj
2
Vnořenou podmínkou následovanou klíčovým slovem break definujeme konec cyklu.
Iterace  1 
Iterace  2 
Iterace  3 
Iterace  4 

Kromě únikového klíčového slova break po němž cyklus okamžitě skončí je k využití příkaz next, po němž se zbytek příkazů v dané iteraci přeskočí a operátor %||%.

Úloha
    1. Vytvořte cyklus, který pro čísla \(1, 2, 3, 4, 5\) vypíše jejich třetí mocniny
    2. Pro stejná čísla provede kumulativní součet.
    3. Pro číslo n provede výpočet faktorialu.
    4. S pomocí funkce readline() od uživatele požaduje číslo, které vždy vypíše. Pokud je číslo záporné, skončí smyčku.

4.9 Vlastní funkce

K funkce slouží klíčové slovo function, které v závorkách doprovází argumenty sloužící k vnitřní specifikaci funkce.

Kód
x <- rnorm(100)
nejblizsi_hodnota <- function(x, value) {
  x[which(abs(x - value) == min(abs(x - value)))]
}

cat("Hodnota nejblíže 0 z vektoru x je:" , 
    nejblizsi_hodnota(x = x, value = 0))
1
Příklad funkce, která vyhledá nejbližší z hodnot vektoru x k referenční hodnotě value.
Hodnota nejblíže 0 z vektoru x je: -0.001569647

4.10 Rekapitulace

Vyplňte následující formulář bez použití R.

  1. Zvolte platné tvrzení pro data.frame:
  2. Matici je možné vytvořit z vektoru přidáním dimenze:
  3. Co je výsledkem výrazu: \(\sin(\frac{0}{0})\)
  4. Vyberte, platné tvrzení pro list:
  5. Napište výraz pro nepřiřazenou číselnou hodnotu :
  6. Dolňte chybějící zápis cyklu:
  for(i in 1:5) {
    cat(___)    
  }
  > 54321