NMSA230 - Úvod do programování v R
Zimný semester 2024/2025 | Cvičenie 5 | Po 02/12/24
• zdrojový Rmd súbor
Program R (dostupný pod GNU GPL licenciou) je k dispozícii k
stiahnutiu (free of charge) na adrese
https://www.r-project.org
K dispozícii sú distribúcie s priamou podporou pre OS Windows, Linux
aj Macintosh.
Základnú inštaláciu programu R je možne jednoducho rozšíriť pomocou
dodatočných knižníc (balíčkov), ktoré sú k dispozícii na rôznych online
repozitároch (zoznam hlavných repozitárov je na adrese
https://cran.r-project.org/mirrors.html).
Jednotlivé R knižnice sú tvorené samotnými užívateľmi softwaru R a ich
správne fungovanie nie je garantované - je preto namieste určitá
opatrnosť a hlavne aktívne premýšľanie pri ich používaní.
Pre užívateľov programu R sú k dispozícii aj rôzne grafické
rozhrania, ktoré je možne dodatočne nainštalovať a umožňujú (v určitých
smeroch) jednoduchšiu a prehľadnejšiu prácu. Najznámejší a pravdepodobne
aj jeden z najlepších R interfacov je
RStudio.
Užitočné materiály pre prácu so štatistickým softwarom
R
-
Bína, V., Komárek, A. a Komárková, L.: Jak na jazyk R.
(PDF súbor)
-
Komárek, A.: Základy práce s R. (PDF
súbor)
-
Kulich, M.: Stručný úvod do R. (PDF
súbor)
-
Scott, T.: An Introduction to R
(PDF súbor)
-
De Vries, A. a Meys, J.: R for Dummies. (ISBN-13: 978-1119055808)
Cieľom piatého semináru NMSA 230 je práca s reálnymi datami, názorná
ukážka jednoduchých simulácii a tiež R knižnica Knitr
(ktorá slúži na prípravu HTML Markdown-u, ako je napríklad táto HTML
stránka).
V. Analýza dat pomocou knižnice Knitr
(HTML)
Tématicky tento seminár naväzuje na minulý seminár, ktorého cieľom
bolo ukázať a vyskúšať si vzájomne prepojenie a fungovanie programu R s
programom LaTeX (pričom toto vzájomné prepojenie a spolupráca oboch
programov je užitočná hlavne v prípade vytvárania rôznych PDF reportov s
výsledkami štatistickej analýzy).
Analogickým spôsobom je prepojený aj program R so štandardným
zdrojovým kódom HTML stránok – a slúži k tomu R knižnica
knitr .
1. Knižnica ‘Knitr’
Knitr (GNU General Public License) je knižnica pre štatistický
program R, ktorá umožňuje integráciu R-kového zdrojového kódu
do HTML jazyka (v určitom zmysle analogickým spôsobom, ako knižnica
Sweave umožňovala integráciu programu R a LaTeXu).
Výslednym produktom knižnice Knitr je súbor html (ale
využitie knižnice je všeobecnejšie a umožňuje aj kompiláciu do PDF
dokumentu, prípadne do .doc súboru), ktorý je možné prezerať
pomocou internetového prehliadača. Takto bola vytvorená napríklad aj
táto html stránka (zdrojový kód stránky je v
tomto súbore).
Inštalácia a inicializácia knižnice pomocou štandardných
príkazov:
install.packages("knitr")
library("knitr")
U niektorých grafických interface (napr. RStudio) môže byť už tento
balíček nainštalovaný štandardne a volanie príslušnej funkcie je
redukované iba na stlačenie príslušného tlačítka Knit v hlavnom
menu. Vstupným suborom je podkladový súbor typu Rmd, ktorý
obsahuje jednak zdrojový kód pre html stránku (prípadne php zdrojovým
kódom) a tiež vhodne označené príkazy pre program R. Pri kompilácii
podkladového súboru sú R-kové príkazy najprv vyhodnotené a výsledky sú
dopĺnené do zdrojového html kódu.
Niekoľko príkladov využitia knižnice ‘Knitr’ v programe R v podobe
podkladových Rmd súborov z predchádzajúcich seminárov (niektoré z
nich ale môžu pri kompilácii vyžadovať súbory, ktoré nejsou automatickou
súčasťou podkladového Rmd súboru - v takom prípade napr. postači
príslušnú časť zdrojového kódu zmazať). Podkladové Rmd súbory je
možné otvoriť v programe RStudio (UTF8 kódovanie – v menu programu
využiť možnosť Reopen with encoding ) a následne skompilovať
stlačením tlačítka “Knit” na hlavnej lište (na hlavnom paneli).
-
podkladový súbor z prvého cvičenia predmetu NMSA230:
Rmd súbor (kódovanie UTF8);
-
podkladový súbor z druhého cvičenia predmetu NMSA230:
Rmd súbor (kódovanie UTF8);
-
podkladový súbor z tretieho cvičenia predmetu NMSA230:
Rmd súbor (kódovanie UTF8);
-
podkladový súbor zo štvrtého cvičenia predmetu NMSA230:
Rmd súbor (kódovanie UTF8);
-
podkladový súbor z piateho cvičenia predmetu NMSA230:
Rmd súbor (kódovanie UTF8);
2. Štatistická analýza a jednoduché
štatistické simulácie
Nasledujúci príkaz načíta reálne data, ktoré zaznamenávajú rôzne
informácie o tehotných pacientkách a následných pôrodoch na
gynekologickom oddelení v Liptovskom Mikuláši. Data sú v pôvodnom
tvare/formáte, ako ich poskytli samotní lekári.
data <- read.csv("http://www.karlin.mff.cuni.cz/~maciak/NMSA230/gynData.csv", header = T, dec = ".", sep = "")
Data obsahujú niekoľko rôznych premenných z ktorých väčšina je
momentálne pre naše účely nepodstatná. V prevažnej väčšine sa ale jedná
o rôzne lekárske kritéria, výsledky konkrétnych tehotenských testov, čí
prípadné výskyty rôznych komplikácii (informácia v tvare pozitívny
výsledok vs. negatívný výsledok) a tiež hodnoty testov na tehotensku
cukrovku (veličiny glik1 až glik4 ). Doplnené
sú niektoré základné popisné charakteristiky pacientky (vek, výška,
hmotnosť, BMI), popisné charakteristiky narodeného dieťaťa (pohlavie,
obvod hlavy a hrudníka, dĺžka, váha, systolický a diastolický krvný tlak
a ďalšie).
names(data)
## [1] "nove" "povodne" "glik1" "glik2" "glik3"
## [6] "glik4" "Vek" "Parita" "GestVek" "PrekoncHm"
## [11] "PorHm" "Vyska" "BMIinic" "BMIfinal" "weightGain"
## [16] "pohlavie" "obvodhrud" "obvodHlava" "dlzka" "sTK"
## [21] "dTK" "Apgar1" "Apgar5" "Apgar10" "cisarskyREX"
## [26] "cisarskyVEX" "DYSTOKIO" "sposobPorodu" "PEE" "hospit"
## [31] "velkyPlod" "malyPlod" "hmotnost" "HYPERBILIRUb" "Bilirubin"
## [36] "ATB" "POLYCYTEMIA" "Hematokrit" "HYPOGLYKEMIA" "Glykemia"
## [41] "PORANENIE" "TRANSFUZIE"
Podstatné ale je prehliadnúť si data a uvedomiť si niektoré chyby
(napr. hodnota pz je najskôr preklep a jedná sa o pozitívnu
hodnotu testu; podobne hodnota nn asi najskôr značí
negatívny výsledok):
table(data$cisarskyREX)
##
## neg pn poz
## 491 1 213
table(data$cisarskyVEX)
##
## neg poz
## 1 693 11
table(data$hospit)
##
## neg nn poz
## 569 1 135
Tieto chyby opravíme pomerne jednoducho, nakoľko sa jedná o
jednoduché korekcie. V zložitejších prípadoch je ale vhodné pamätať na
možnosti, ktoré v programe R máme vďaka jeho schopnosti pracovať s tzv.
regularnými výrazmi (napr. príkazy grep() ,
grepl() , sub() , gsub() ,
regexpr ()`, atď.).
data$cisarskyREX[which(data$cisarskyREX == "pn")] <- "poz"
data$cisarskyREX <- factor(data$cisarskyREX, levels = c("neg", "poz"))
data$cisarskyVEX[which(data$cisarskyVEX == "")] <- "neg"
data$cisarskyVEX <- factor(data$cisarskyVEX, levels = c("neg", "poz"))
data$hospit[which(data$hospit == "nn")] <- "neg"
data$hospit <- factor(data$hospit, levels = c("neg", "poz"))
Z určitých expertných dôvodov je pre lekárov doležite rozlíšiť staré
a nové kritéria (prvé dva stĺpce v datach). Zavedieme preto novú
premennú, ktorá bude súhrnne popisovať výsledky oboch kritérii:
data$kriteria <- rep("neg", dim(data)[1])
data$kriteria[data$nove == "poz" & data$povodne == "neg"] <- "posNove"
data$kriteria[data$nove == "neg" & data$povodne == "poz"] <- "posPovd"
data$kriteria[data$nove == "poz" & data$povodne == "poz"] <- "posBoth"
data$kriteria <- as.factor(data$kriteria)
table(data$kriteria, data$nove)
##
## neg poz
## neg 611 0
## posBoth 0 18
## posNove 0 64
## posPovd 12 0
table(data$kriteria, data$povodne)
##
## neg poz
## neg 611 0
## posBoth 0 18
## posNove 64 0
## posPovd 0 12
Takto nejak by mohol v praxi vyzerať tzv. ``data processing step’’,
ktorý je väčšinou nutnou súčasťou pri každom štatistickom spracovaní a
vyhodnotení dat. Úpravy v datach by sa mali vždy robiť pomocou samotného
programu a príslušného skritpu, ktorý všetky zásahy v datach zaznamenáva
prostredníctvom zdrojového kódu (spätná traktabilita/vystopovatelnosť
všetkých zásahov, ktore sa s datami robili).
Samostatne
-
Podívajte sa na data a pokúste sa spočítať niektoré základné popisné
charakteristiky. Tieto charakteristiky doplňte o vhodne zvolené obrázky,
ktoré budú popisné charakteristiky vizuálne reprezentovať.
-
Pokúste sa pomocou popisných charakteristík povedať niečo podstatné o
starých a nových kritériach vzhledem na výskyt rôznych komplikácii
(rozlišujte pacientky v závislosti na výsledkoch starých a nových
kriterii, resp. na novo-zavedenej premennej
kriteria ).
-
Pomocou popisných charakteristík novorodenca sa pokúste ponúknuť odpoveď
na otázku, či je rozdiel medzi novonarodeným chlapcom a novonarodenou
holkou.
V nasledujúcej časti sa zameriame pouze na hmotnosť novonarodených
deti (premenná hmotnost ). Histogram so zaznamenanými
hodnotami vyzera takto (pre lepšiu vizuálizáciu je súčasťou histogramu
aj neparametrický odhad hustoty a hustota normálneho rozdelenia so
strednou hodnotou rovnou výberovému priemeru a rozptylom rovným
výberovému rozptylu):
hist(data$hmotnost, xlab= "Hmotnosť novorodenca", freq = F, ylab= "Relatívny výskyt", main = "", col = "lightblue", breaks = 20)
lines(density(data$hmotnost), col = "red", lwd = 2)
lines(dnorm(seq(1500, 5000, length = 10000), mean(data$hmotnost), sd(data$hmotnost)) ~ seq(1500, 5000, length = 10000), col = "blue", lty = 2)

Formálne by sme mohli napríklad otestovať, čí namerané hodnoty výšky
novorodencov pochádzajú z normálneho rozdelenia (nulová hypotéza), alebo
pochádzajú z nejakého iného rozdelenia (alternatívna hypotéza). Na
testovanie takto definovanej nulovej hypotézy máme v teórii
pravdepodobnosti a v štatistike niekoľko rôznych testov, ktoré ale nie
sú ekvivalentné.
-
Kolmogorov-Smirnovov test – v programe R implementovány v príkaze
ks.test() ;
ks.test(data$hmotnost,"pnorm",mean=mean(data$hmotnost),sd=sd(data$hmotnost),exact=FALSE)
##
## One-sample Kolmogorov-Smirnov test
##
## data: data$hmotnost
## D = 0.048552, p-value = 0.07203
## alternative hypothesis: two-sided
Shapiro-Wilkův test – v programe R implementovány v príkaze
shapiro.test() ;
shapiro.test(data$hmotnost)
##
## Shapiro-Wilk normality test
##
## data: data$hmotnost
## W = 0.99016, p-value = 0.0001164
Jarque-Bera test – v programe R implementovány v knižnici
tseries v príkaze jarque.bera.test() ;
library(tseries)
jarque.bera.test(data$hmotnost)
##
## Jarque Bera Test
##
## data: data$hmotnost
## X-squared = 21.75, df = 2, p-value = 1.893e-05
\(\boldsymbol{\chi}^2\) test
dobrej zhody – k testovaniu normality by bolo možné využiť napr. aj
\(\chi^2\) test dobrej zhody (v rôznej
jeho komplexnosti a zložitosti). Pre výberovy priemer váho novorodenca
máme \(\overline{X}_n \approx
3414.8\)
mean(data$hmotnost)
## [1] 3414.851
a pre výberovú smerodatnú chybu \(S_n
\approx 487.3\)
sd(data$hmotnost)
## [1] 487.3607
Za predpokladu normality by teda štandardizované hodnoty \((X_i - \overline{X}_n)/S_n\), pre \(i = 1, \dots, n\) mali mať štandardné
normálne rozddelenie \(N(0,1)\). Z
pravdepodobnostnej teórie vieme, že \(P[X <
-1] \approx 0.1586\) a tiež \(P[X >
1] \approx 0.1586\), kde \(X \sim
N(0,1)\). Inými slovami, v intervale \([-1,1]\) (t.j. \(\pm \sigma\) je približne \(68.28~\%\) celkovej pravdepodobnostnej
masy). To znamená, že za platnosti nulovej hypotézy o normalite by
približne \(!5.86~\%\) z hodnôt \((X_i - \overline{X}_n)/S_n\) malo byť
menších (rovných), než hodnota \(-1\),
približne \(34.14~\%\) hodnôt by malo
byť väčších ako \(-1\), ale menších
(rovných) ako nula, rovnako cca \(34.14~\%\) hodnôt by malo byť väčších ako
nula, ale menších (rovných) ako 1 a konečne, zostávajúcich \(15.86~\%\) hodnôt by malo byť väčších ako
1.
I1 <- sum((data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) <= -1)
I2 <- sum((data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) > -1 & (data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) <= 0 )
I3 <- sum((data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) > 0 & (data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) <= 1 )
I4 <- sum((data$hmotnost - mean(data$hmotnost))/sd(data$hmotnost) > 1)
Za platnosti nulovej hypotézy o normalite by vektor \((I_1, I_2, I_3, I_4)^\top\) mal mať
multinomické rozdelenie s vektorom parametrov (proporcii) \(\boldsymbol{p}_0 = (0.1586, 0.3414, 0.3414,
0.1586)^\top\). Pomocou testu dobrej zhody teda môžeme otestovať
nulovú hypotézu, že parameter \(\boldsymbol{p}
= (p_1, p_2, p_3, P_4)^\top\) (t.j., skutočné pravdepodobnosti v
multinomickom rozdelení) je rovný hodnotam v \(\boldsymbol{p}_0\).
p0 <- c(0.1586, 0.3414, 0.3414, 0.1586)
chisq.test(c(I1, I2, I3, I4), p0)
##
## Pearson's Chi-squared test
##
## data: c(I1, I2, I3, I4) and p0
## X-squared = 4, df = 3, p-value = 0.2615
Rozhodnutie o nulovej a alternatívnej hypotéze je rôzne na základe
rôznych testov. Ako si vybrať ten správny test? K odpovedi nám pomôže
mala simulačná štúdia, ktorá sa bude zameriavať na sílu jednotlivých
testov (to je pravdepodobnosť, že test zamietne nulovú hypotézu, ak
nulová hypotéza neplatí). Toto sa práve simuluje následujúci príklad, v
ktorom testujeme (použitím rôznych testov), čí náhodný výber pochádza z
rovnomerného rozdelenia, pričom vďaka simuláciam vieme, že výber z
normálneho rozdelenia nepochádza – pretože data simulujeme z \(\chi^2\) rozdelenia.
N <- c(10, 50, 100, 200, 500, 1000, 2000, 5000)
power <- NULL
set.seed(1234)
for (n in N){
p1 <- p2 <- p3 <- p4 <- NULL
for (i in 1:100){
x <- rchisq(n, df = 50) ### pozorovania simulujeme z chi^2 rozdelenia
I1 <- sum((x - mean(x))/sd(x) <= -1)
I2 <- sum((x - mean(x))/sd(x) > -1 & (x - mean(x))/sd(x) <= 0 )
I3 <- sum((x - mean(x))/sd(x) > 0 & (x - mean(x))/sd(x) <= 1 )
I4 <- sum((x - mean(x))/sd(x) > 1)
p1 <- c(p1, as.numeric(ks.test(x,"pnorm",mean=mean(x),sd=sd(x),exact=FALSE)$p.value < 0.05))
p2 <- c(p2, as.numeric(shapiro.test(x)$p.value < 0.05))
p3 <- c(p3, as.numeric(jarque.bera.test(x)$p.value < 0.05))
p4 <- c(p4, as.numeric(chisq.test(c(I1, I2, I3, I4), p0)$p.value < 0.05))
}
power <- rbind(power, c(n, mean(p1), mean(p2), mean(p3), mean(p4)))
}
plot(power[,2] ~ log10(power[,1]), col = "red", type = "l", pch = 21, bg = "red", xlab = "Logarimus rozsahu náhodného výberu", ylab = "Empirická síla testu", ylim = c(0,1))
lines(power[,3] ~ log10(power[,1]), col = "blue")
lines(power[,4] ~ log10(power[,1]), col = "green")
lines(power[,5] ~ log10(power[,1]), col = "violet")
points(power[,2] ~ log10(power[,1]), pch = 21, bg = "red")
points(power[,3] ~ log10(power[,1]), pch = 21, bg = "blue")
points(power[,4] ~ log10(power[,1]), pch = 21, bg = "green")
points(power[,5] ~ log10(power[,1]), pch = 21, bg = "violet")
abline(1,0, col = "black", lty = 3)
legend(1, 1, legend = c("Kolmogorov-Smirnov test", "Shapiro-Wilk test", "Jarque-Beta test", "Chi-kvadrat test"), col = c("red", "blue", "green", "violet"), lty= rep(1,3))

S9la testu (empirická) by mala pre rastúci rozsah náhodného výberu –
na ose x — konvergovať k jednotke… inými slovami, štatistický test je
konzistentný a pravdepodobnosťou idúcou k jednej sa rozhodne nulovú
hypotézu zamietnúť, ak je táto hypotéza nepravdivá.
Z tohto pohľadu je najsilnejším testom práve Shapiro-Wilkov test. Je
potrebné ale pamätať na to, že testy boli spočítane pri konkrétnej
alternatíve - skutočné rozdelenie bolo \(\chi^2\) rozdelenie s 50 stupňami voľnosti.
Jak sa ale porovnanie v zmysle síly testu zmení, ak zmeníme postup a
generovať budeme data z \(t\)
rozdelenia s ťažkými chvostmi (t.j. nízke stupne voľnosti)?
N <- c(10, 50, 100, 200, 500, 1000, 2000, 5000)
tdf <- c(2, 5, 10, 50)
set.seed(1234)
PWR <- list()
for (d in 1:length(tdf)){
power <- NULL
for (n in N){
p1 <- p2 <- p3 <- NULL
for (i in 1:100){
x <- rt(n, df = tdf[d])
p1 <- c(p1, as.numeric(ks.test(x,"pnorm",mean=mean(x),sd=sd(x),exact=FALSE)$p.value < 0.05))
p2 <- c(p2, as.numeric(shapiro.test(x)$p.value < 0.05))
p3 <- c(p3, as.numeric(jarque.bera.test(x)$p.value < 0.05))
}
power <- rbind(power, c(n, mean(p1), mean(p2), mean(p3), mean(p4)))
}
PWR[[d]] <- power
}
par(mfrow = c(2,2))
for (d in 1:length(tdf)){
power <- PWR[[d]]
plot(power[,4] ~ log10(power[,1]), col = "red", type = "l", pch = 21, bg = "red", xlab = "Logarimus rozsahu náhodného výberu", ylab = "Empirická síla testu", main = paste("t rozdelenie (df = ", tdf[d],")", sep = ""), ylim = c(0,1))
points(power[,4] ~ log10(power[,1]), pch = 21, bg = "red")
points(power[,3] ~ log10(power[,1]), pch = 21, bg = "blue")
points(power[,2] ~ log10(power[,1]), pch = 21, bg = "green")
lines(power[,3] ~ log10(power[,1]), col = "blue")
lines(power[,2] ~ log10(power[,1]), col = "green")
abline(1,0, col = "black", lty = 3)
legend(1, 1, legend = c("Shapiro-Wilk test", "Jarque-Beta test", "Kolmogorov-Smirnov test"), col = c("blue", "red", "green"), lty= rep(1,3), cex = 0.5)
}

Pri danej alternatíve - studentovo \(t\) rozdelenie s 5 stupňami voľnosti sa
zdá, že najsilnejším testom je Jarque-Bera test.
Samostatne
-
Dokážete vysvetliť sledované správanie sa síly jednotlivých testov?
-
Použijte podobnú simulačnú štúdiu pre iné alternatívy a pre iné
štatistické testy.
-
Rozmyslite si podobnú simulačnú štúdiu nižšie, ktorej cieľom by bolo
porovnávať dosiahnutú/empirickú hladinu.
-
Dokážete vysvetliť sledované rozdiely v jednotlivých obrázkoch?
Nasledúca časť kódu ukazuje simululácie vzhľadom k hladine testu – to
je dosiahnutá (empirická) pravdepodobnosť chyby prvého druhu – t.j.
pravdepodobnosť, že nulovú hypotézu zamietneme, ak nulová hypotéza
platí.
Preto v následujúcom príklade generujeme data z normálneho rozdelenia
– t.j. za platnosti nulovej hypotézy a pri zvolenej teoretickej hladine
\(\alpha = 0.05\) sledujeme, ako často
sa test zmýli – tzv., že zamietne nulovú hypotézu (p-hodnota testu bude
menšia, než \(\alpha\)). Správny test
by empiricky držať zvolenú teoretickú hladinu \(\lpha \in (0,1)\).
N <- c(10, 50, 100, 200, 500, 1000, 2000, 5000)
set.seed(1234)
power <- NULL
for (n in N){
p1 <- p2 <- p3 <- NULL
for (i in 1:100){
x <- rnorm(n)
p1 <- c(p1, as.numeric(ks.test(x,"pnorm",mean=0,sd=1,exact=FALSE)$p.value < 0.05))
p2 <- c(p2, as.numeric(shapiro.test(x)$p.value < 0.05))
p3 <- c(p3, as.numeric(jarque.bera.test(x)$p.value < 0.05))
}
power <- rbind(power, c(n, mean(p1), mean(p2), mean(p3)))
}
par(mfrow = c(1,1))
plot(power[,4] ~ log10(power[,1]), col = "red", type = "l", pch = 21, bg = "red", xlab = "Logarimus rozsahu náhodného výberu", ylab = "Dosiahnutá hladina testu", main = "", ylim = c(0,0.4))
points(power[,4] ~ log10(power[,1]), pch = 21, bg = "red")
points(power[,3] ~ log10(power[,1]), pch = 21, bg = "blue")
points(power[,2] ~ log10(power[,1]), pch = 21, bg = "green")
lines(power[,3] ~ log10(power[,1]), col = "blue")
lines(power[,2] ~ log10(power[,1]), col = "green")
abline(0.05,0, col = "black", lty = 2, lwd =2)
legend(1, 0.4, legend = c("Shapiro-Wilk test", "Jarque-Beta test", "Kolmogorov-Smirnov test"), col = c("blue", "red", "green"), lty= rep(1,3))

3. Program R: Čo sa ešte oplatí vedieť,
alebo aspoň tušiť?
Niekoľko (snáď) zaujímavých námetov na samostatnú aktivitu…
A) Vlastné funkcie a súbory typu
.R a .RData
Program R umožňuje vytváranie rôznych užívateľských funkcií.
Vytvorené funkcie je možné jednoducho uložiť do datového súboru typu
.R a pri opätovnom načítaní súboru pomocou R príkazu
source() , sú funkcie opäť k dispozícii. Nasledujúcim
príkazom načítame do programu R vlastné preddefinované funkcie:
rm(list = ls())
source("http://www.karlin.mff.cuni.cz/~maciak/NMSA230/mojeFunkce.R")
Vpodstate sa jedna k štandardný R skript, ktorý je uložený pomocou
príkazu save() .
Súbor obsahuje jednu preddefinovanú užívateľskú funkciu
mojaFunkce1() , ktora je definovaná následovne:
mojaFunkce1 <- function(x){
m <- mean(x)
v <- var(x)
return(paste("Sample mean and sample variance: ", round(m, digits = 2), " (", round(var(x), digits = 3), ")", sep = ""))
}
Štandardným volaním funkcie pomocou jej ména (t.j.
mojaFunkce1() ) funkciu aplikujeme na konkrétny numerický
vektor:
mojeFunkce1(rnorm(1000))
V podkladovom súbore je možné okrem samotných funkcii ukládať aj iné
Rkové objekty - napr. výsledky parciálných výpočtov, simulácii a
podobne. Nejedná sa ale o samotné objekty vo vorme hotových výsledkov,
ale o podkladový Rkový zdrojový kód, ktorý tieto výsledky pri načítaní
súboru vyhodnotením zdrojového kódu vytvorí. Načitaním podkladového
.R súboru teda zakaždým dôjde k samotnému výpočtu a vyhodnoteniu
všetkých príkazov, ktoré sú v súbore definované. Tento postup samozrejme
nie je ideálny v prípade, keď sú výpočty časovo náročné a skôr by sme
ocenili pouze jednorázové vyhodnotenie a následne odkazovanie sa na
hotové výsledky - v programe R k tomu slúži práve datový typ, R súbor
typu .RData.
Nasledujúci príkaz načíta do programu R dva objekty - náhodné výbery
o rozsahu 10000, avšak samotné generovanie náhodých výberov už
neprebieha, dôjde pouze k načítaniu výsledných hodnôt dvoch náhodných
výberov. Samotné generovanie prebehlo vrámci R skriptu, ktorý načítaním
súboru nemáme už k dispozícii.
load(url("http://www.karlin.mff.cuni.cz/~maciak/NMSA230/hotoveVysledky.RData"))
Náhodné výbery su (v skutočnosti) vygenerované zo štandardného
normálneho rozdelenia a z exponenciálneho rozdelenia so strednou
hodnotou 1. Nastavenie seedu bolo zakždým set.seed(1) .
Empiricky môžeme tvrdenie jednoducho overiť:
set.seed(1)
newSample1 <- rnorm(10000)
sum(newSample1 == sample1)
## [1] 10000
Samostatne
-
V programe RStudio otvorte ako R skript súbor mojeFunkce.R, ktorý
stiahnete
tu
a vytvorte niekoľko ďalších vlastných funkcii. Analogicky môžete využiť
a iný vhodný textový editor. Výsledny súbor opäť uložte, načitajte v
programe R a vytvorené funkcie aplikujte.
-
Vytvorte jednoduchú sumulačnú štúdiu, ktorej parciálne výsledk budete
postupne ukládať do súboru typu .RData. Je potrebné ukladanie
súboru vhodne implementovať, aby nedochádzalo k prepisovaniu ukladaných
výsledkov.
-
Porovnajte fungovanie R príkazov
source() a
load() .
Užítočné
-
Dôležité a často používané užívaťeľské funkcie je výhodné uložiť v
samostatnom súbore typu .R a podkladový súbor načítať pomocou
príkazu
source() . Do tohto súboru by mal užívateľ ideálne
zasahovať iba vo výnimočnych prípadoch, keď je nutné konkrétnu funkciu
pozmeniť, alebo nadefinovať novú.
-
Postup práce a priebeh (štatistickej) analýzy dat vo forme postupnosti
konkrétnych príkazov a riadkov zdrojového kódu je opäť vhodné uložit ako
.R súbor, ale z dôvodu častého zasahovania do tohto súboru je
doporučené, aby sa jednalo o iný súbor, než ten, v ktorom sú uložené
základné uživateľské funkcie.
-
Jednotlivé riadky zdrojového kódu je užitočne náležite (a dostatočne
podrobne) komentovať a k názvom jednotlivých premenných a objektov
používať intuitivné značenie.
### komentar v programe R, resp. v subore typu .R
mojaFunkce1(x)
B) Datové súbory typu .xls,
.csv, alebo .txt
V praxi sa štatistík stretáva najčastejšie s datami ktoré sú
reprezentované číselne, väčšinou pomocou tabuľky, ktorá je uložená buť v
Exceli, alebo v textových súboroch typu .csv a .txt.
Vyššie spomínaný datový súbor .RData je ideálný pre ukladanie
samotných objektov vytvorených v programe R, resp. niektoré vzorové
datové súbory určené k výukovým účelom bývajú taktiež uloženém v súbore
typu .RData. Tieto objekty nemusia nutne reprezentovať štandardný
súbor vo forme tabuľky s hodnotami. Pre uloženie konkrétnych dat vo
forme tabuľky sú možno praktickejšie klasické textové súbory typu
.xls, .txt, alebo .csv. Pre manipuláciu so súbormi
slúžia funkcie read.table() (príkaz z R knižnice ‘gdata’),
read,csv() a read.table() .
Help k príkazom:
?read.table
?write.table
K uloženiu datovych súborov (ideálne vo forme tabuľky, resp.
data.frame() slúžia v programe R príkazy
write.xlsx() (z knižnice ‘xlsx’), write.csv()
alebo write.table() . K dispozícii je ale množstvo iných
knižníc, ktoré ponúkajú alternatívne príkazy buď pre načítanie dat z
Excel súboru, alebo dokonca načítanie informácie zo súborov iných typov
(napr. obrázky, videa, zvykové záznamy a pod.).
Samostatne
-
Vytvorte nejaké konkrétne data, alebo využijte datové súbory ktoré sú
predinštalované v programe R (príkaz
data() ) a konkrétnu
tabuľku s jednotlivými premennými a pozorovaniami uložte a načítajte ako
datové typy .txt, alebo .csv.
-
Pomocou vhodných dodatočných parametrov sa pokuste formu uložených dat
pozmeniť a následne opätovne načítať tak, aby nedošlo k zmene, alebo
strate pôvodnej informacie (napr. dodatočné parametre ‘sep’, ‘dec’,
‘skip’, ‘na.string’, ‘as.is’, …).
-
Pre manipuláciu s datami a hlavne veľkými datovými súbormi sú v
programe R užitočné knižnice
install.packages("dplyr")
install.packages("plyr")
Viac informácii o oboch knižniciach a niekoľko vzorových príkladov
napríklad tu:
https://www.rdocumentation.org/packages/dplyr/versions/0.7.8
alebo tu
https://seananderson.ca/2013/12/01/plyr/.
-
Užítočne je hlavne podívať sa na funkcie ako
aggregate() ,
apply() , sapply() , lapply() ,
alebo mapply() .
-
Nainštalujte si knižnicu
jpeg (viac podrobnosti napr.
tu)
a pomocou príkazu readJPEG() načítajte do programu R nejaky
obrázok/fotografiu. Podívajte sa, aký objekt ste do programu načítali a
pokúste sa tento objekt nejakým sposobom zmeniť. Výsledný/modifikovaný
objekt pomocou príkazu writeJPEG() opäť uložte a na obrázok
sa podívajte pomocou programu na prezeranie obrázkov.
C) Čo ešte na záver?
Program R využívame hlavne ako nástroj na prípravu a následnú analýzu
dat. Program R je možné taktiež využiť k príprave reportu, ktorý k
štatistickej analýze väčšinou automaticky patrí. Takýto report by mal
obsahovať úvod a zmysluplný popis samotného experimentu, z ktorého data
pochádzajú. Taktiež musí dostatočne podrobný popis samotných dat. Z
odborného (matematického a štatistického) hľadiska musí obsahovať aj
dostatočne presné informácie o použitých metódach pri štatistickom
vyhodnotení. Popis musí byť natoľko podrobný, aby s pomocou popisu bolo
možné celkový experiment a šštatistickú analýzu replikovať. Závery
analýzy ale musia byť interpretované v reči pôvodných dat a to spôsobom,
ktorému aj nematematik a neštatistik pochopí. Pri výtvárani takéhoto
reportu je užitočné využiť program LaTeX, balíček Sweave, alebo R
funkciu cat() .
Nie vždy sme ale nútení pripraviť report v PDF formáte. Na druhej
strane by ale malo vždy platiť, že samotné zdrojové kódy,defaultné
označenie premenných, alebo výstupy z Rkových funkcii by sa v reporte
objavovať nemali. To platí aj rôzne tabuľky (napr. tabuľka popisných
charakteristík, ako výstup funkcie summary() ). V takomto
prípade môže byť užitočné poznať R knižnicu ‘formattable’ - viac na
https://www.littlemissdata.com/blog/prettytables.
Možnosti programu R sú vpodstate neobmedzené, zaujímavý pohľad na
možné nadstavy a rozšírenia ponúka webová stránka
https://awesome-r.com/.
Samostatne
-
Pre účely zápočtu máte pripravený R skript, ktorý obsahuje generovanie
dat, jednoduché popisné charakteristiky, vytvorenie obrázkov, aj
následne reportovanie pomocou knižnice
Sweave . Vyberte si
niektorú konkrétnu časť zdrojového kódu a pokúste sa v nejakom zmysle
fungovanie programu v danej časti kódu zefektivniť.
-
Program R ponúka množstvo rôznych nástrojov (napr. rôzne R knižnice) na
vytváranie grafických výstupov – obrázkov. Pokúste sa alespoň jeden
obrázok vypracovať nejakým alternatívnym spôsobom – t.j., napr. s
použitím iného R-kového baličku (knižnice).
|