Kapitola 1 Úvod do R

R je prostredie pre štatistické výpočty a vizualizáciu údajov vyvíjané pod slobodnou licenciou a pre rôzne platformy, inštalačné súbory resp. návod na inštaláciu ako aj dokumentáciu je možné nájsť na domovskej stránke projektu www.r-project.org. Základom je interpretovaný počítačový jazyk R umožňujúci vetvenie, cyklenie a modulárne programovanie pomocou funkcií. Distribúcia R obsahuje funkcionalitu pre veľký počet štatistických metód ako lineárne a zovšeobecnené lineárne modely, nelineárnu regresiu, analýzu časových radov, klasické parametrické a neparametrické testy, zhlukovú analýzu a vyhladzovanie, ďalej množstvo funkcií poskytuje flexibilné prostredie pre grafickú reprezentáciu údajov, no najväčšou výhodou R je obrovská a voľne dostupná databáza prídavných balíčkov tvorených komunitou používateľov z akademickej i komerčnej sféry. Základné prostredie R (inštalácie v systéme Windows) tvorí textový editor, pomocou ktorého používateľ píše zdrojový kód v jazyku R, a príkazový riadok (konzola), ktorý odoslaný kód interpretuje. Grafické výstupy sú presmerované do samostatných okien. Pre pohodlnú prácu odporúčame použitie integrovaného vývojového prostredia RStudio, ktoré farebne zvýrazňuje syntax, poskytuje nápovedu, sprístupňuje zoznam definovaných objektov, uľahčuje tvorbu dokumentácie a veľa ďaľších užitočných nástrojov. Zdrojový kód sa na interpretáciu do príkazového riadku posiela typicky buď po riadkoch alebo vyznačením jeho časti, a stlačením kombinácie kláves Ctrl-R (v prostredí RStudio Ctrl-Enter).

1.1 R ako lepšia kalkulačka

R sa dá použiť podobne ako kalkulačka na rôzne jednoduché výpočty a zobrazenie, pričom základný výstup z príkazového riadku je čisto textový a tak tradičný matematický zápis matematických symbolov ako napr. \(\sqrt{x^3}\) nepodporuje.

1.1.1 Základné matematické operátory a funkcie

Najčastejšou operáciou je sčítanie. Po prijatí textového vstupu v príkazovom riadku (začína sa znakom >) systém R vypíše výsledok, v nasledujúcom príklade je to číslo 5. Keďže však v R je všetko nejaká forma poľa, aj jediné číslo je uložené vo forme vektora, a to dĺžky 1. Výpis dlhších vektorov sa v konzole zalamuje do riadkov, pričom každý začína indexom prvého elementu v danom riadku. To vysvetľuje reťazec [1] pred výsledkom nášho príkladu.

> 2+3
[1] 5

V nasledujúcom texte prispôsobíme formátovanie textu tak, aby vstup a výstup nezaberal príliš veľa miesta v našej publikácii (zlúčime okienka do jedného), zároveň aby sa vstup dal pohodlne kopírovať do svojho skúšobného scriptového súboru (odstránime >) a aby sa výstup líšil od vstupu (bude začínať znakmi ##). Krátke poznámky budú uvádzané za znakom pre komentár (#).

Pokračujme základnými matematickými operátormi a matematickými funkciami, ktoré sú dostupné na bežných kalkulačkách:

3/2
## [1] 1.5

2^3
## [1] 8

4 ^ 2 - 3 * 2 # násobenie má prednosť pred odčítaním
## [1] 10

(56-14)/6 - 4*7*10/(5^2-5) # často je potrebné použiť zátvorky
## [1] -7

sqrt(2)  # pomenovaná funkcia pre odmocnenie 
## [1] 1.414214

abs(2-4)        # |2-4|
## [1] 2

cos(4*pi)       # ďaľšie sú sin(), tan(), atan(), atan2() ...
## [1] 1

log(0)      # funkcia pre tento argument nie je definovaná
## [1] -Inf
exp(1)    # eulerovo číslo
## [1] 2.718282

factorial(6)   # 6!
## [1] 720

choose(52,5)   # kombinačné číslo 52!/(47!*5!)
## [1] 2598960

1.1.2 Priradenie hodnoty premennej

Často treba s hodnotami počítať viackrát, vtedy sa hodí uložiť ich do premennej. Možností uloženia je v R niekoľko:

n <- 5   # klávesová skratka [Alt] + [-]
n
## [1] 5

15 -> n; n
## [1] 15

assign("n", 25)

n = 35  # radšej nepoužívať, (esteticky) vyhradené pre zadávanie argumentov funkcie

(n <- 2*3)   # tri v jednom: vypočíta, priradí a vypíše hodnotu
## [1] 6

1.1.3 Vektory

Podobne ako s jednoprvkovým vektorom sa pracuje s ľubovoľne dlhým vektorom. Najprv hodnoty skombinujeme do vektorov:

x <- c(1,2,3,4)      
y <- c(5,6,7,8)

Väčšina operácií v R je vektorizovaná, preto sa aplikujú postupne na všetky prvky vektora, resps. zodpovedajúce si prvky viacerých vektorov:

x*y; y/x; y-x; x^y   # väčšina funkcií v R je vektorizovaná
## [1]  5 12 21 32
## [1] 5.000000 3.000000 2.333333 2.000000
## [1] 4 4 4 4
## [1]     1    64  2187 65536

cos(x*pi) + cos(y*pi)
## [1] -2  2 -2  2

s <- c(1,1,3,4,7,11)
length(s)       # dĺžka vektora
## [1] 6

sum(s)          # 1+1+3+4+7+11
## [1] 27

prod(s)         # 1*1*3*4*7*11
## [1] 924

cumsum(s)  # 1, 1+1, 1+1+3, ...
## [1]  1  2  5  9 16 27

diff(s)        # 1-1, 3-1, 4-3, 7-4, 11-7
## [1] 0 2 1 3 4

diff(s, l=2)  # 3-1, 4-1, 7-3, 11-4
## [1] 2 3 4 7

1.1.4 Matice a polia

Matice ako dvojrozmerné pole sa zväčša vytvára z vektorov

a <- c(1,2,3,4,5,6,7,8,9,10)
A <- matrix(a, nrow = 5, ncol = 2)  # napĺňanie matice sa štandardne deje po stĺpcoch
A
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10

B <- matrix(a, nrow = 5, ncol = 2, byrow = TRUE) # napĺňanie po riadkoch
B
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8
## [5,]    9   10

C <- a
dim(C) <- c(5,2)    # matica je vektor, ktorý dostal dva rozmery

C <- t(C)       # transponovanie
C
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    3    4    5
## [2,]    6    7    8    9   10

B %*% C             # násobenie
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   13   16   19   22   25
## [2,]   27   34   41   48   55
## [3,]   41   52   63   74   85
## [4,]   55   70   85  100  115
## [5,]   69   88  107  126  145

D <- C %*% B
D
##      [,1] [,2]
## [1,]   95  110
## [2,]  220  260

det(D)
## [1] 500

solve(D)        # inverzia matice (riešenie D*x=I, kde I je jednotková m.)
##       [,1]  [,2]
## [1,]  0.52 -0.22
## [2,] -0.44  0.19

cbind(x,y)      # lepenie vektorov do stĺpcov, resp. do riadkov matice
##      x y
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
rbind(x,y)
##   [,1] [,2] [,3] [,4]
## x    1    2    3    4
## y    5    6    7    8

E <- letters[1:(4*2*3)]   # `letters` je zabudovaná databáza písmen v abecednom poradí
dim(E) <- c(4,2,3)    # z vektora trojrozmerné pole
E   # výpis vo forme dvojrozmerných rezov
## , , 1
## 
##      [,1] [,2]
## [1,] "a"  "e" 
## [2,] "b"  "f" 
## [3,] "c"  "g" 
## [4,] "d"  "h" 
## 
## , , 2
## 
##      [,1] [,2]
## [1,] "i"  "m" 
## [2,] "j"  "n" 
## [3,] "k"  "o" 
## [4,] "l"  "p" 
## 
## , , 3
## 
##      [,1] [,2]
## [1,] "q"  "u" 
## [2,] "r"  "v" 
## [3,] "s"  "w" 
## [4,] "t"  "x"

1.1.5 Vstup údajov

ovocie <- c("jablko", "hruška", "pomaranč")

1:9         # sekvencia s krokom 1
## [1] 1 2 3 4 5 6 7 8 9

1.5:10      # nedostaneme sa az po koniec, no ten môžeme pridať
## [1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
c(1.5:10,10)
##  [1]  1.5  2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5 10.0

seq(-2,5)    # to isté ako -2:5, ale seq() dokáže i viac...
## [1] -2 -1  0  1  2  3  4  5

seq(-2,5,by=.5)     # prírastok o 0.5
##  [1] -2.0 -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0

seq(-2,5,length=4)  # dĺžka sekvencie bude práve 4
## [1] -2.0000000  0.3333333  2.6666667  5.0000000

rep(9,5)    # opakuj číslo 9 päť-krát
## [1] 9 9 9 9 9

rep(1:4,2)
## [1] 1 2 3 4 1 2 3 4
rep(1:4, each = 2)
## [1] 1 1 2 2 3 3 4 4
rep(1:4, each=2, times=3)
##  [1] 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4
rep(1:4,1:4)
##  [1] 1 2 2 3 3 3 4 4 4 4

matrix(rep(c(1,rep(0,4)),4), nrow=4, ncol=4)  # i takto sa dá vytvoriť jednotková matica 4x4
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1
diag(1, nrow=4)     # no takto je to predsalen jednoduchšie :)
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1

Iné spôsoby vloženia údajov zahŕňajú vstup z klávesnice

vstup <- scan()     # postupne zadavanie z klavesnice (na konci Enter naprazdno)

alebo zo súboru, kedy je dobré najprv nastaviť pracovný adresár

setwd(choose.dir(default = "", caption = "Select folder")) # interaktívne
setwd("F:\\cesta\\ku/súboru")  # explicitne

potom použiť scan, read.table alebo iné funkcie

vstup <- read.table("subor.txt", header = TRUE, sep = "", dec=".", skip=1)

kde začne druhým riadkom a hodnoty by mali byť oddelené "bielymi’ znakmi (medzera, tab, nový riadok).

1.1.6 Manipulácia s prvkami pola

Výber prvkov poľa (subsetting) sa dá mnohými spôsobmi

z <- c(y,x); z
## [1] 5 6 7 8 1 2 3 4

z[1]
## [1] 5
z[5:8]          # výpis konkretnych prvkov
## [1] 1 2 3 4
z[c(5,8)]
## [1] 1 4

z[-(2:8)]       # vyberie všetky okrem prvkov zadaných zápornym indexom
## [1] 5
z[-c(5,8)]
## [1] 5 6 7 8 2 3

z[8] <- 10      # ôsmemu prvku je priradená ina hodnota

z > 5           # vysledkom je vektor logických hodnôt
## [1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE

z[z>5 & z<7]          # výber všetkých prvkov väčších ako 5
## [1] 6

(1:20)[c(TRUE,FALSE)]   # všetky nepárne (lebo vektor logických hodnôt sa replikuje)
##  [1]  1  3  5  7  9 11 13 15 17 19

A
##      [,1] [,2]
## [1,]    1    6
## [2,]    2    7
## [3,]    3    8
## [4,]    4    9
## [5,]    5   10
A[1,2]          # prvok z 1.riadku a 2.stĺpca matice A
## [1] 6
A[1,,drop=F]    # prvý riadok
##      [,1] [,2]
## [1,]    1    6
A[,2]           # druhý stlpec
## [1]  6  7  8  9 10
A[,2,drop=F]
##      [,1]
## [1,]    6
## [2,]    7
## [3,]    8
## [4,]    9
## [5,]   10

1.2 Jednoduché grafy

plot(sin, from=0, to=2*pi, xlab="os x")  # použije plot.function


par(mfrow=c(1,2))      # rozdelenie zobrazovanej oblasti do matice 1x2

x <- seq(0, 2*pi, length=16+1)    # diskrétne body
plot(x,sin(x),type="o", lty="dashed")

plot(x, sin(x), type="p", pch="+")      # graf dvojíc {x[i],sin(x[i])}
lines(x, sin(x), col="red", lty="dashed")   # spojnice sú pridané do predošlého grafu


par(mfrow=c(1,1))     # nastavenie mriežky grafického okna vrátime na pôvodné hodnoty

Export obrázku do súboru sa deje presmerovaním grafického výstupu do tzv. grafického zariadenia (device), napr. pre formáty PNG, BMP, JPEG, PDF a ďalšie. Prvý príkaz dané zariadenie otvorí, posledný zavrie.

png(file="sinus.png", width=600, height=400, units="px")
plot(sin, from=0, to=2*pi) 
dev.off()

Demonštračné ukážky základnej grafiky, 2D či 3D, si možno pozrieť pomocou generickej funkcie demo.

demo(graphics)
demo(persp)

Ukážky pokročilejšej grafiky nájdeme najmä na internete:

1.3 Dátove objekty

Základnými dátovými objektami používanými v R sú vector, factor, matrix, array, data frame, ts a list.

Sú charakterizované menom, obsahom ale aj atribútmi, ktoré špecifikujú typ obsahu. Základnými atribútmi sú dĺžka (length) a typ (mode). Ďalšími sú napr. rozmer (dimension) pri viacrozmerných pravidelných objektoch ako matrixm, array či data.frame, ďalej trieda (class), či

Typy dátových objektov sú numeric, character, complex, logical, function, expression, a ďalšie.

Iba data frame a list môžu obsahovať viac ako jeden typ.

1.3.1 vector

V nasledujúcich príkladoch vytvoríme nový vektor zadaním dĺžky, módu a konkrétneho prvku. Nezadané hodnoty sú doplnené prednastavenými, napr. dĺžka rovná nule alebo ostatné prvky rovné FALSE (ekvivalentom v numerickom móde je nula), prípadne nie sú definované vôbec (NA vo význame “not available”).

v <- vector(mode="logical", length=0); v
## logical(0)

Nový vektor dĺžky 0 je predurčený obsahovať logické hodnoty “ano” alebo “nie”, alternatívne aj v <- logical().

v <- logical(); v[2] <- TRUE; v              
## [1]   NA TRUE
v <- logical(3); v[2] <- TRUE; v
## [1] FALSE  TRUE FALSE

1.3.2 factor

Dátový typ factor je (interne) vektor obsahujúci iba prirodzené čísla (poradové čísla, indexy) a atribút levels (úrovne), v ktorom sú uložené jedinečné hodnoty vo forme znakových reťazcov. Navonok sa zobrazuje ako vektor týchto reťazcov postupne vyberaných z levels svojim indexom.

v <- c(10,40,40,30,40,30)
fv <- factor(v); fv
## [1] 10 40 40 30 40 30
## Levels: 10 30 40
str(fv)  # úspornejšie uskladnenie v pamäti
##  Factor w/ 3 levels "10","30","40": 1 3 3 2 3 2
fv*2  # factor je hybrid medzi character a numeric
## Warning in Ops.factor(fv, 2): '*' not meaningful for factors
## [1] NA NA NA NA NA NA
as.numeric(fv)*2  # konverzia vráti iba indexy úrovní
## [1] 2 6 6 4 6 4
as.numeric(as.character(fv))
## [1] 10 40 40 30 40 30

1.3.3 matrix

Dátový typ matica je (interne) len vektor s atribútom dim (dimensions, rozmery) obsahujúcim počet riadkov a počet stĺpcov matice, pričom hodnoty vektora sú do matice napĺňané po stĺpcoch

A <- 1:12
dim(A) <- c(2,6)    # ďalší atribút, nepatri medzi základné (non-intrinsic)
A
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    7    9   11
## [2,]    2    4    6    8   10   12

matrix(1:12, nrow=2)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    7    9   11
## [2,]    2    4    6    8   10   12

1.3.4 data frame

Dátový objekt data frame sa na prvý pohľad tvári ako matica, ale na rozdiel od nej môže mať stĺpce odlišného typu. Interne je to skôr list s rovnakou dĺžkou všetkých prvkov, takže sa dá zobraziť ako tabuľka. Každý stĺpec zvyčajne predstavuje jednu pozorovanú veličinu a každý riadok jedno pozorovanie (pre každú veličinu). Ak napríklad na križovatke pozorujeme, koľko pasažierov je v každom aute a či sú všetci pripútaní bezpečnostným pásom, výsledný súbor údajov vo forme tabuľky data frame môže vyzerať nasledovne:

pocet_pasazierov <- c(1,3,2,5,2,2,1,1,2,1)
priputani <- c(T,T,F,T,F,F,T,F,F,T)
auta <- data.frame(pocet_pasazierov,priputani)
auta
##    pocet_pasazierov priputani
## 1                 1      TRUE
## 2                 3      TRUE
## 3                 2     FALSE
## 4                 5      TRUE
## 5                 2     FALSE
## 6                 2     FALSE
## 7                 1      TRUE
## 8                 1     FALSE
## 9                 2     FALSE
## 10                1      TRUE

Interaktívna editácia je možná, ale málokedy používaná:

auta <- edit(auta)  #vytvorte tretiu premennu "mesta" so skratkami miest
auta

Interná štruktúra dátového objektu:

attributes(auta)
## $names
## [1] "pocet_pasazierov" "priputani"       
## 
## $class
## [1] "data.frame"
## 
## $row.names
##  [1]  1  2  3  4  5  6  7  8  9 10
str(auta)
## 'data.frame':    10 obs. of  2 variables:
##  $ pocet_pasazierov: num  1 3 2 5 2 2 1 1 2 1
##  $ priputani       : logi  TRUE TRUE FALSE TRUE FALSE FALSE ...

R obsahuje mnoho vlastných súborov dát, príkazom data() sa otvorí ich zoznam v samostatnom okne (na samostatnej záložke), vyberieme z nich napríklad merania priemeru, výšky a objemu na vzorke stromov.

data()  
data(trees)  # načítanie dátového súboru, ktorý je súčasťou R
trees
##    Girth Height Volume
## 1    8.3     70   10.3
## 2    8.6     65   10.3
## 3    8.8     63   10.2
## 4   10.5     72   16.4
## 5   10.7     81   18.8
## 6   10.8     83   19.7
## 7   11.0     66   15.6
## 8   11.0     75   18.2
## 9   11.1     80   22.6
## 10  11.2     75   19.9
## 11  11.3     79   24.2
## 12  11.4     76   21.0
## 13  11.4     76   21.4
## 14  11.7     69   21.3
## 15  12.0     75   19.1
## 16  12.9     74   22.2
## 17  12.9     85   33.8
## 18  13.3     86   27.4
## 19  13.7     71   25.7
## 20  13.8     64   24.9
## 21  14.0     78   34.5
## 22  14.2     80   31.7
## 23  14.5     74   36.3
## 24  16.0     72   38.3
## 25  16.3     77   42.6
## 26  17.3     81   55.4
## 27  17.5     82   55.7
## 28  17.9     80   58.3
## 29  18.0     80   51.5
## 30  18.0     80   51.0
## 31  20.6     87   77.0

Z tabuľky potom možno prvky vyberať rôznymi spôsobmi (subsetting)

trees[c("Girth","Height")]  # konkrétne stĺpce ich názvom
##    Girth Height
## 1    8.3     70
## 2    8.6     65
## 3    8.8     63
## 4   10.5     72
## 5   10.7     81
## 6   10.8     83
## 7   11.0     66
## 8   11.0     75
## 9   11.1     80
## 10  11.2     75
## 11  11.3     79
## 12  11.4     76
## 13  11.4     76
## 14  11.7     69
## 15  12.0     75
## 16  12.9     74
## 17  12.9     85
## 18  13.3     86
## 19  13.7     71
## 20  13.8     64
## 21  14.0     78
## 22  14.2     80
## 23  14.5     74
## 24  16.0     72
## 25  16.3     77
## 26  17.3     81
## 27  17.5     82
## 28  17.9     80
## 29  18.0     80
## 30  18.0     80
## 31  20.6     87
trees[1]  # konkrétny stĺpec jeho poradím; alebo napr. trees[c(1,2)]
##    Girth
## 1    8.3
## 2    8.6
## 3    8.8
## 4   10.5
## 5   10.7
## 6   10.8
## 7   11.0
## 8   11.0
## 9   11.1
## 10  11.2
## 11  11.3
## 12  11.4
## 13  11.4
## 14  11.7
## 15  12.0
## 16  12.9
## 17  12.9
## 18  13.3
## 19  13.7
## 20  13.8
## 21  14.0
## 22  14.2
## 23  14.5
## 24  16.0
## 25  16.3
## 26  17.3
## 27  17.5
## 28  17.9
## 29  18.0
## 30  18.0
## 31  20.6
trees[[1]]  # výsledkom nie je data.frame ale vektor
##  [1]  8.3  8.6  8.8 10.5 10.7 10.8 11.0 11.0 11.1 11.2 11.3 11.4 11.4 11.7 12.0
## [16] 12.9 12.9 13.3 13.7 13.8 14.0 14.2 14.5 16.0 16.3 17.3 17.5 17.9 18.0 18.0
## [31] 20.6
trees$Girth  # opäť vektor
##  [1]  8.3  8.6  8.8 10.5 10.7 10.8 11.0 11.0 11.1 11.2 11.3 11.4 11.4 11.7 12.0
## [16] 12.9 12.9 13.3 13.7 13.8 14.0 14.2 14.5 16.0 16.3 17.3 17.5 17.9 18.0 18.0
## [31] 20.6

Premennú Girth v globálnom prostredí nemáme …

Girth
## Error in eval(expr, envir, enclos): object 'Girth' not found

… až pokým doň nepripojíme data.

attach(trees)  
Girth
##  [1]  8.3  8.6  8.8 10.5 10.7 10.8 11.0 11.0 11.1 11.2 11.3 11.4 11.4 11.7 12.0
## [16] 12.9 12.9 13.3 13.7 13.8 14.0 14.2 14.5 16.0 16.3 17.3 17.5 17.9 18.0 18.0
## [31] 20.6
detach(trees)

Prístup k premenným môže byť aj lokálne.

with(trees, head(Girth) )  
## [1]  8.3  8.6  8.8 10.5 10.7 10.8

Výber riadkov podla zadaných podmienok a výber stĺpcov:

subset(trees, subset = Height>80 & Girth>10.0, select=Height:Volume)
##    Height Volume
## 5      81   18.8
## 6      83   19.7
## 17     85   33.8
## 18     86   27.4
## 26     81   55.4
## 27     82   55.7
## 31     87   77.0
trees[trees$Height>80 & trees$Girth>10.0, c("Height","Volume")]
##    Height Volume
## 5      81   18.8
## 6      83   19.7
## 17     85   33.8
## 18     86   27.4
## 26     81   55.4
## 27     82   55.7
## 31     87   77.0

1.3.5 list

Zoznam (list) je najvšeobecnejší, môže obsahovať rôzne dátové objekty, nielen vektor.

List1 <- list(polozka1=c(1,2,3), polozka2=c("hruska","jablko"), polozka3=FALSE)
List1  # nemusí mať rovnaký počet riadkov/stĺpcov (na rozdiel od predošlých objektov)
## $polozka1
## [1] 1 2 3
## 
## $polozka2
## [1] "hruska" "jablko"
## 
## $polozka3
## [1] FALSE

Subsetting funguje podobne ako pri data frame.

1.3.6 ts (time series)

Dátový typ ts je iba vektor s atribútom tsp, ktorý obsahuje začiatočný čas, koncový čas a niečo ako základnú periódu, zvyčajne sezónnu.

ts(1:10, start=1959)
## Time Series:
## Start = 1959 
## End = 1968 
## Frequency = 1 
##  [1]  1  2  3  4  5  6  7  8  9 10

cr <- ts(rnorm(20), frequency = 12, start=c(1959,1))

plot(cr)   # lepši výsledok externým balíkom pomocou plot(xts::as.xts(cr))

1.3.7 expression

Tento dátový typ je užitočný napr. pri symbolických výpočtoch alebo zobrazení vzorcov v grafoch.

x <- 3; y <- 2.5; z <- 1
výraz <- expression(x/(y+exp(z)))
výraz
## expression(x/(y + exp(z)))
eval(výraz)
## [1] 0.5749019

D(výraz, "y")
## -(x/(y + exp(z))^2)

1.3.8 Konverzia medzi dátovymi objektami

as.numeric(c(TRUE,FALSE))
## [1] 1 0
as.numeric("4")
## [1] 4
as.numeric(c("A","Z"))
## Warning: NAs introduced by coercion
## [1] NA NA
as.logical(c(-1,0,1,2))
## [1]  TRUE FALSE  TRUE  TRUE
as.logical(c("FALSE","F"))
## [1] FALSE FALSE
as.logical("A")
## [1] NA
as.character(1)
## [1] "1"
as.character(TRUE)
## [1] "TRUE"
as.numeric( factor(c(0,100,36.7,100)) )
## [1] 1 3 2 3
as.numeric(as.character( factor(c(0,100,36.7,100)) ))
## [1]   0.0 100.0  36.7 100.0

1.4 Operátory

  • aritmetické: + - * / ^ %%(modulo) %/% (celočíselné delenie)
  • porovnávacie: < > <= >= == !=
  • logické: ! & && | || xor
  • ďalšie operátory R: $ @ [ [[ : ? <- <<- ::

Prioritu pri vyhodnocovaní príkazov dokumentuje stránka v nápovede:

?Syntax     # zoznam operátorov podla priority

Používanie logických operátorov:

x <- 2
y <- z <- 1:3
LO <- c(F,F,F)

0 < x & x < 1     # skrátený zápis 0 < x < 1 NEfunguje
## [1] FALSE

x < y | LO        
## [1] FALSE FALSE  TRUE
x < y || LO       # zdvojený logický operátor si všíma iba prvý prvok vektorov
## [1] FALSE

Porovnávanie

y == z            # porovnanie po prvkoch
## [1] TRUE TRUE TRUE
identical(y, z)   # porovnanie objektov ako 'celku'
## [1] TRUE
all.equal(y, z)
## [1] TRUE

môže byť pri zaokrúhľovaní na úrovni strojovej presnosti zradné

0.9 == 1.1 - 0.2            # porovnanie numerických hodnôt
## [1] FALSE
identical(0.9, 1.1 - 0.2)
## [1] FALSE
all.equal(0.9, 1.1 - 0.2)
## [1] TRUE
all.equal(0.9, 1.1 - 0.2, tolerance = 1e-16)
## [1] "Mean relative difference: 1.233581e-16"

1.5 Programovanie

1.5.1 Cykly a podmienky

Podmienky a cykly sa dajú zapísať pomocou rovnakých slov ako v známom jazyku C: if, else, for, while, repeat, break, next.

Majme údaje uložené v data frame

data <- data.frame(
  a = 1:5,
  b = runif(5),
  c = c(2,0.3,4,-1,0)
); data
##   a          b    c
## 1 1 0.43361572  2.0
## 2 2 0.99083235  0.3
## 3 3 0.08368043  4.0
## 4 4 0.86255486 -1.0
## 5 5 0.12968316  0.0

pre ktorý chceme zistiť medián každého stĺpca. Môžme na to ísť so sekerou

median(data$a)
## [1] 3
median(data$b)
## [1] 0.4336157
median(data$c)
## [1] 0.3

alebo motorovou pílou,

vysledok <- vector("double", ncol(data))     
for (i in 1:length(vysledok)) {          
  vysledok[i] <- median(data[[i]])      
}
vysledok
## [1] 3.0000000 0.4336157 0.3000000

prípadne laserovým mečom ako v Hviezdnych vojnách.

sapply(data, median)
##         a         b         c 
## 3.0000000 0.4336157 0.3000000

Príklad s kontrol-slovami if, next a break:

a = 0
for (i in 1:20) {
  a = i^2
  if(a <= 10 ) {
    cat('a = ', a, '(<= 10)'); cat('\n')
    next
  }
  if(a == 144) {
    cat('a = ', a); cat('\n')
    break
  }
}
## a =  1 (<= 10)
## a =  4 (<= 10)
## a =  9 (<= 10)
## a =  144
i     # hodnota iteracnej premennej nie je po skonceni cyklu vymazana
## [1] 12

Monte-Carlo odhad hodnoty Ludolfovho čísla:

eps <- 1; s <- 0; n <- 0   # inicializačné hodnoty
while(eps > .001) {
  n <- n + 1                    # počet generovaných bodov
  x <- runif(1,-1,1)                # súradnice náhodného bodu v štvorci
  y <- runif(1,-1,1)                # [-1,-1][1,-1][1,1][-1,1]
  if(x^2 + y^2 < 1) s <- s + 1  # počet bodov ležiacich vnútri kruhu s polomerom 1
  pihat <- 4*s/n                # odhad 'pi'
  eps = abs(pihat - pi)         # s toleranciou 'eps'
}
pihat     # odhad
## [1] 3.141243
n         # počet iterácií
## [1] 177

Náhodný výpis z N(0,1) rozdelenia, kým čislo nepresiahne hodnotu 1.6 (funkcia set.seed nastaví generátor pseudonáhodných čísel, aby bolo možné neskôr zreprodukovať výsledok):

set.seed(123)  
repeat {a <- rnorm(1); if (a > 1.6) break; cat(a); cat("\n")}
## -0.5604756
## -0.2301775
## 1.558708
## 0.07050839
## 0.1292877

1.5.2 Vlastné funkcie

Vytvoríme jednoduchú kvadratickú funkciu a zavoláme ju s argumentom x = 3:

f <- function(x) x^2
f(3)
## [1] 9

Táto funkcia vráti maximum dvoch skalárnych čísel alebo hlášku o ich rovnosti:

f1 <- function(a, b) {
  if(is.numeric(c(a,b))) {
    if(a < b) return(b)
    if(a > b) return(a)
    else print("Hodnoty su rovnake")
  }
  else print("Akceptujem iba cisla.")
}
f1(4,7)
## [1] 7
f1(0,exp(log(0)))
## [1] "Hodnoty su rovnake"
f1("Adam","Eva")
## [1] "Akceptujem iba cisla."

1.5.3 Vyhnutie sa cyklom -> vektorizácia

Ak chceme vypočítať priemer stĺpcov matice M

M <- cbind(rnorm(20,0,1), rnorm(20,-5,1))

namiesto klasických vnorených for-cyklov

suma <- numeric(m <- NCOL(M)); n <- NROW(M);
for(i in 1:n) {
  for(j in 1:m) {
    suma[j] <- suma[j] + M[i,j]
  }
}
suma/n   # priemer hodnôt v stĺpcoch
## [1] -0.2601434 -4.7793464

je efektívnejšie použiť funkciu apply (v tomto prípade existuje náhrada colMeans(M))

apply(M, MARGIN=2, FUN=mean)  # pre MARGIN=1 by FUN bola aplikovaná na riadky
## [1] -0.2601434 -4.7793464

Funkcia apply m8 niekoľko modifikácií: lapply, sapply, mapply, tapply a replicate.

Namiesto vstavanej funkcie možno ako argument FUN aplikovať vlastnú (aj nepomenovanú) funkciu

sapply(c(-1,0,5,-5,9), function(x) if(x>0) x else 0)
## [1] 0 0 5 0 9

alebo túto funkciu pomenovať a namiesto vloženia do sapply ju explicitne vektorizovať, napr.

f2 <- function(prvy, druhy) {
  if(prvy > druhy) prvy else if(druhy>prvy) druhy else NA
}
f2(prvy = c(-1,2,10), druhy = c(2,2,2))   # testuje iba prvy prvok z oboch argumentov
## Warning in if (prvy > druhy) prvy else if (druhy > prvy) druhy else NA: the
## condition has length > 1 and only the first element will be used
## Warning in if (druhy > prvy) druhy else NA: the condition has length > 1 and
## only the first element will be used
## [1] 2 2 2
f2 <- Vectorize(f2)
f2(dru = c(2,2,2), pr = c(-1,2,10))  # argumenty stačí písať unikátnou skratkou
## [1]  2 NA 10

Vektorizovanou náhradou za if(cond) expr1 else expr2 je ifelse(cond,expr1,expr2).

a <- c(-1,2,10); b <- c(2,2,2)
ifelse(a > b, a, b)           # v tomto prípade ma rovnaký efekt aj pmax(a,b)
## [1]  2  2 10

1.5.4 Prostredie lokálnych premenných

Niekedy chceme urobiť výpočet s pomocnými premennými, ktoré nemajú byť globálne viditeľné, napríklad preto, aby neprepísali hodnotu nejakej existujúcej s rovnakým menom:

a <- 0
local({
  b <- a
  a <- 8
  a + b
})
## [1] 8
a
## [1] 0

Ako lokálne premenné sa dajú použiť aj prvky objektu typu list alebo data.frame:

with(data, a+1)
## [1] 2 3 4 5 6

1.6 Poznámky

1.6.1 Rôzne

Ak uložíme definície funkcií a premenných do súboru, povedzme mojeprogramy.r, môžme ich kedykoľvek použiť v inom skriptovom súbore pripojením source("mojeprogramy.r").

Užitočná vec pri hľadaní chýb vo vlastnej funkcii (debugging) je umiestniť funkciu browser() do tela funkcie. Po zavolaní našej funkcie nám sprístupní jej prostredie so všetkými lokálnymi premennými.

1.6.2 Pôvod jazyka

Čo je R? Odpoveď je jednoduchá. R je dialekt jazyka S.

Jazyk S neprišiel spomedzi tradičných programovacích jazykov, cieľom jeho autorov bolo vymyslieť, ako uľahčiť analýzu údajov … kľúčovým tu bol prechod od používateľa ku vývojárovi.

R si zachovalo pôvodnú filozofiu jazyka S, teda poskytnúť jednak interaktivitu pri práci, ale aj možnosti vývoja nových nástrojov. Technicky je bližšie skôr ku jazyku Scheme než ku S.

Výhody:
- R je voľne dostupný pod licenciou GNU GPL,
- beží na ľubovoľnej štandardnej počítačovej platforme a operačnom systéme,
- aktívny vývoj,
- sofistikované zobrazovacie schopnosti,
- aktívna komunita používateľov

Podrobnejšie sa vzniku a vlastnostiam R venuje časť (R. D. Peng 2016, kap. 2 History and Overview of R).

1.7 Študijná literatúra

Manuály v slovenčine/češtine:
* seriál na IT spravodajskom portáli Root.cz https://www.root.cz/serialy/programovaci-jazyk-r/ (Tišňovský 2020)
* od študentov http://rmanual.fri.uniza.sk/
* Jak pracovat s jazykem R https://www.math.muni.cz/~kolacek/vyuka/vypsyst/navod_R.pdf

Manuály a tématicky zameraná literatúra vo svetovom jazyku:
* https://cran.r-project.org/other-docs.html
* https://bookdown.org/

Zábavná literatúra:
* YaRrr! The Pirate’s Guide to R https://bookdown.org/ndphillips/YaRrr/
* The R inferno https://www.burns-stat.com/pages/Tutor/R_inferno.pdf

Odporúčané:
* Advanced R http://adv-r.had.co.nz/ (Wickham 2019)
* R for data science http://r4ds.had.co.nz/ (Wickham a Grolemund 2016)
* R style guide https://style.tidyverse.org

Prehľad balíkov:
* Tématický https://cran.r-project.org/web/views/
* Najpopulárnejšie https://support.rstudio.com/hc/en-us/articles/201057987-Quick-list-of-useful-R-packages
* Výber balíkov aj iného: https://awesome-r.com/

História a stručný pohlad napr. https://bookdown.org/rdpeng/rprogdatascience/history-and-overview-of-r.html
Úvod: https://moderndive.com/1-getting-started.html

1.8 Cvičenie

  1. Načítajte súbor údajov mtcars z balíka datasets a uložte ho do premennej s názvom dat.
  2. Zobrazte štruktúru objektu dat a prvých 5 riadkov.
  3. Preveďte premennú mpg na jednotky km/l a uložte ako novú premennú kml do toho istého objektu.
  4. Vytvorte logický vektor aut indikujúci, či ide o auto s automatickou prevodovkou a pomocou neho vypočítajte priemerný dojazd (v km na 1l paliva) automobilov zvlášť s automatickou a zvlášť s manuálnou prevodovkou.
  5. Zobrazte tabuľku všetkých áut s piatimi rýchlostnými stupňami a hmotnosťou do 3000 libier, ktorá obsahuje iba údaje o počte valcov, zdvihovom objeme a výkone motora.
  6. Vytvorte funkciu na prevod jednotiek, ktorá bude mať 3 argumenty (s názvom)[s hodnotami]: prevádzanú hodnotu (x), imperiálnu jednotku (impunit)[míľa, galón, palec, libra], smer prevodu do SI (toSI)[TRUE,FALSE], pričom zodpovedajúcimi jednotkami v metrickej sústave SI budú km, l, dm, kg. (Využite pri tom funkciu switch a automatickú konverziu módu vektora toSI z logického na numerický.)
  7. Pomocou for cyklu skonvertujte hodnoty zdvihového objemu valcov z kubických palcov na litre. Pomocou funkcie sapply preveďte hmotnosť vozidiel na tony. Zachovajte pri tom pôvodné názvy premenných a použite funkciu na prevod jednotiek z predošlej úlohy.
  8. Nastavte pracovný adresár a načítajte tabuľku údajov zo súboru mtcars.txt (uloženého v pracovnom adresári) do objektu typu data.frame. Dbajte pri tom na správne nastavenie parametrov importu ako počet riadkov neštrukturovaného popisu, prítomnosť názvu stĺpcov, oddelovací znak desatinných miest, znak oddelujúci stĺpce tabuľky a znak chýbajúcich hodnôt (NA). Porovnajte načítaný data frame s pôvodným dat.