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).
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.
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
Č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
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
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"
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).
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
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 dvojic {x[i],sin(x[i])}
lines(x, sin(x), col="red", lty="dashed") # čiary spájajúce diskrétne body 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:
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.
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
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
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
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
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 # list 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.
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))
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)
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
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"
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.3485037 2.0
## 2 2 0.3637000 0.3
## 3 3 0.3795673 4.0
## 4 4 0.4516245 -1.0
## 5 5 0.8350941 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.3795673
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.3795673 0.3000000
prípadne laserovým mečom ako v Hviezdnych vojnách.
sapply(data, median)
## a b c
## 3.0000000 0.3795673 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.141463
n # počet iterácií
## [1] 205
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
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."
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
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
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.
Č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ť (Peng 2016, kap. 2 History and Overview of R).
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
Niektoré návody na vytvorenie reportu z výpočtov pomocou značkovacieho jazyka Rmarkdown:
* https://bookdown.org/yihui/rmarkdown
* https://rmarkdown.rstudio.com
* http://www.stat.cmu.edu/~cshalizi/rmarkdown/
* https://ismayc.github.io/rbasics-book/ (videá)
* https://holtzy.github.io/Pimp-my-rmd
* https://yongfu.name/Rmd_ref/
* http://www.datadreaming.org/post/r-markdown-theme-gallery/