Biomatematika gyakorlat Ez az útmutató a SZIE ÁOTK állatorvos szakos hallgatók számára készült a biomatematika tantárgy gyakorlataihoz.
Első gyakorlat A félév során leginkább statisztikát tanulunk. Azokat a módszereket gyűjtöttük össze, amelyek egy TDK dolgozat, szakdolgozat elkészítéséhez hasznosak lehetnek. Természetesen a leendő kutatók is hasznát veszik majd a tanultaknak. Az első gyakorlaton a statisztikai programmal ismerkedünk. A kézi átlagszámításnak a XXI. században már lejárt az ideje. A tanuláshoz az R programot használjuk, melynek számos előnye van. Ez egyik legfontosabb előny, hogy teljesen ingyenes. A programmal kapcsolatos minden információ megtalálható a http://www.r-project.org/ címen. Onnét lehet letölteni is. A telepítéshez egy másik dokumentum nyújt segítséget, melyet a gyakorlatvezetők megmutatnak. További előnyök, hogy széles körben elfogadják és a legújabb statisztikai módszerek is gyorsan elérhetőek benne. Indítás után a program így néz ki:
Alaposabb szemrevételezés után feltűnik, hogy nincsenek olyan menüpontok, melyek bármiféle statisztikai tevékenységre alkalmassá tennék a programot. Ennek oka, hogy eredetileg ezt a programot úgy tervezték, hogy az érdeklődők begépelik azokat a parancsokat, melyeknek az
eredményét látni szeretnék. Ennek eredményeként a kezelés kellőképpen bonyolult volt, nagy odafigyelést igényelt. Egyetlen gépelési hiba is komoly gondokat (jobb esetben hibaüzenetet, rosszabb esetben hibás eredményt) okozott. Érdemes tudni, hogy ezt nem a fejlesztők önsanyargatása miatt készítették ilyenre, hanem azért, mert a valóságban gyakran előfordul, hogy egy kísérletet többször ki kell értékelni. Tipikus példa, mert mire a cikk leadható állapotba kerül, új egyedeken is sikerült adatokat gyűjteni. Jó lenne, ha az új mérések is bekerülnének az elemzésbe. Ebben az esetben az egész folyamatot módosítás nélkül meg kell ismételni az elemzéskor. A gépeléses módszer előnye, hogy a korábban elmentett szöveget vissza lehet tölteni, és az abban levő parancsokat újra le lehet egyetlen gombnyomással futtatni, megspórolva ezzel néhány tíz, de akár több száz egérkattintást a grafikus felületen. Azok, akik sokat dolgoznak a programmal, egy idő után már ezt a módszert érzik kényelmesnek. Mi az egyszerűbb megoldást választjuk majd, és elindítunk egy grafikus felületet, ahol elég lesz kattintgatni. Mielőtt azt elindítanánk, az alapdolgokkal azért célszerű megismerkedni. A piros > (úgynevezett prompt) után lehet begépelni a parancsokat. Minden parancsot az ENTER billentyű lenyomásával kell befejezni. Kezdjük néhány egyszerű paranccsal: 5+3 6*8 12/2 10-3 3+6*8
A parancs mindig piros, az eredmény kék színnel jelenik meg.
Ha nem fejezünk be egy parancsot, akkor a > prompt helyett + tudatja velünk, hogy folytatni kell, amit elkezdtünk. Ha hibás parancsot adunk, akkor természetesen hibaüzenetet kapunk. Ha olyan parancsot adunk, melynek eredménye egy vektor, akkor a képernyő bal szélén mindig látjuk szögletes zárójelben, hogy abban a sorban az első látható érték éppen hányadik eleme a vektornak.
Látható, hogy a tizedesvesszőt nem szereti a program, minden esetben tizedespontot használunk. A konzoltól ezek után elbúcsúzunk, és megismerkedünk a legfontosabb paranccsal, amellyel a grafikus felületet (GUI, graphical user interface) indítjuk: library(Rcmdr)
A program megkülönbözteti a kis- és nagybetűket, ezért a parancsot pontosan így kell beírni! A kapott felület már jobba hasonlít arra, amit megszoktunk:
Adatok bevitele Első dolgunk az lesz, hogy létrehozunk egy datasetet. Használjuk a Data/New dataset… menüpontot. Adjunk neki nevet:
Célszerű beszédes nevet adni. Az első gyakorlaton csak néhány adatot gépelünk be a gyakorláshoz. (Később majd Excelből vesszük át az adatokat.)
Van benne egy gépelési hiba. Ilyen néha előfordul, ezért megtanuljuk majd, hogy mit lehet ilyenkor tenni. Hátra van még az oszlopnevek megadása. Ehhez kattintsunk egyesével a var1, var2, var3 feliratokra.
A numeric felirat előtti zöld pötty azt jelenti, hogy ide számokat írtunk be. A másik kettő oszlopnál a pötty a character előtt lesz. Ennek később lesz jelentősége. Például ha valahová véletlenül tizedesvesszőt írtunk, akkor azt onnét lehet megsejteni, hogy character lesz ott, ahol numericnek kellene lennie. Az ablakot a jobb fölső sarokban lehet bezárni. Na használjunk szóközt, ékezetes betűket. Hasonlóan nevezzük el a másik két oszlopot is Ivar és Pancreatitis néven. Ezt kell látnunk:
A jobb fölső sarokban látható X-szel be kell zárni a Data Editor ablakot. Amíg ezt nem tesszük, a program látszólag lefagy. Vigyázat, ne az egész programot zárjuk be! Az aktuális adathalmaz a kék feliratra kattintva változtatható meg:
Ezzel most nem tudunk mit kezdeni, ugyanis még csak egy adathalmazunk (datasetünk) van, és azt sem így hívják, mint az ábrán látszik, de ez ne zavarjon bennünket.
Az adatok megtekintése Az adatokat megnézhetjük a
megnyomásával, vagy a showData(ElsoAdatom)
parancs kiadásával. A gomb megnyomása kicsit bonyolultabb parancsot ad meg, mely meghatározza azt, hogy a táblázat mely sorai jelenjenek meg, mi legyen a betűtípus, valamint mi a maximális szélessége és magassága a megjelenő táblázatnak. showData(ElsoAdatom, placement='-20+200', font=getRcmdr('logFont'), maxwidth=80, maxheight=30)
Minden, amit a menüből kiválasztunk, a felső ablakrészbe beírja helyettünk a megfelelő parancsot. Így aztán ötvözhetjük a kattintgatás és a gépelés előnyeit. Nem kell a parancsokat megjegyezni, viszont a gép által generált parancsokat szükség szerint át tudjuk írni saját céljainknak megfelelően. A parancsok sorozatát, az úgynevezett scriptet el is lehet menteni, és később vissza lehet tölteni, így meglesz az az előny, hogy ha újra kell valamit futtatni, akkor nem kell mindent elölről kezdeni. Az alsó ablakrészben kapjuk majd az eredményeket. Próbáljuk i, hogyan lehet saját parancsot készíteni a gép sugallata alapján. Másoljuk le a script ablakban a showData parancsot (kijelölés, CTRL+C, majd CTRL+V), és változtassuk meg a maxheight értéket 10-re. Jelöljük ki a parancsot és nyomjuk meg a Submit gombot! Ha még nem zártuk be az előző nézegető ablakot, akkor könnyen összehasonlíthatjuk a kettőt.
Jegyezzük meg, hogy minden parancs így működik. Először jön a parancs neve. Mondhatjuk úgy is, hogy a függvénynév, ugyanis az R parancsai valójában függvények. Ahogy a matematikában megszoktuk, a függvények neve után illik zárójelbe tenni a függvény paramétereit. Nincs ez másként itt sem, a paraméterekkel határozzuk meg a függvények pontos viselkedését. Erről majd bővebben értekezünk, ahol szükség lesz rá.
Az adatok módosítása Ha feltétlenül szükséges, az adatok az
megnyomásával, vagy a fix(ElsoAdatom)
paranccsal módosíthatóak. Az adat létrehozásakor már megismert táblázatot látjuk. Vigyázat, amíg a táblázatot nem zárjuk be, a program nem hajt végre további parancsokat!
Leíró statisztika – az adatok szemrevételezése Ebben a részben felderítjük az adataink viselkedését.
Alapadatok Statistics/Summaries/Active data set menü Az aktuális adathalmazról megtudhatjuk az oszlopok nevét. Numerikus adatok esetén megadja a minimumot, maximumot, alsó- és felső kvartilist, mediánt és átlagot. Faktorok esetén megadja, hogy hány megfigyelés tartozik a faktor első néhány szintjéhez. A faktorok olyan oszlopok, amelyek többnyire szöveges adatot tartalmaznak, és arra szolgálnak, hogy az adatokat különböző csoportokba soroljuk, például Ivar vagy betegség szerint. A faktor egy-egy szintje egy-egy csoport, amelyet a megfelelő szöveg jelez. Az Ivar faktornak a példában két szintje van, a H és az N.
summary(ElsoAdatom)
> summary(ElsoAdatom) Glukoz
Ivar
Pancreatitis
: 4.00
H:5
Igen:5
1st Qu.: 6.02
N:6
Ign :1
Min.
Median :14.50 Mean
:13.69
3rd Qu.:20.70 Max.
:23.20
Nem :5
Alapadatok kicsit bővebben Statistics/Summaries/Numerical summaries menü Hasonlít az előzőhöz, de itt meghatározhatjuk, hogy mely változókra vagyunk kíváncsiak. Elvileg többet is ki lehetne jelölni (CTRL+kattintás), de nekünk most csak egy olyan változónk van, amely számokat tartalmaz, így kénytelenek vagyunk azt az egyet választani.
Megadhatjuk, hogy kell-e az átlag, szórás, illetve a minimum, maximum, medián, alsó- és felső kvartilis:
Azt is lehet, hogy nem a kvartiliseket íratjuk ki, hanem azt nézzük meg, hogy mely tartományba esik az adatok első, második, …, ötödik ötöde:
És a funkció legnagyobb erőssége, hogy mindezt csoportonként is ki tudja számolni:
numSummary(ElsoAdatom[,"Glukoz"], statistics=c("mean", "sd", "quantiles"), quantiles=c(0,.25,.5,.75,1)) > numSummary(ElsoAdatom[,"Glukoz"], statistics=c("mean", "sd", "quantiles"), +
quantiles=c(0,.25,.5,.75,1)) mean
sd 0%
13.68545 8.057006
25%
50%
75% 100%
n
4 6.02 14.5 20.7 23.2 11
numSummary(ElsoAdatom[,"Glukoz"], groups=ElsoAdatom$Ivar, statistics=c("mean", "sd", "quantiles"), quantiles=c(0,.25,.5,.75,1))
> numSummary(ElsoAdatom[,"Glukoz"], groups=ElsoAdatom$Ivar, +
statistics=c("mean", "sd", "quantiles"), quantiles=c(0,.25,.5,.75,1))
mean
sd
0%
25%
50%
75% 100% n
H 14.52200 8.683543 4.00 7.91 14.50 23.000 23.2 5 N 12.98833 8.259817 4.39 5.76 13.32 20.475 20.8 6
Gyakoriság-eloszlás Statistics/Summaries/Frequency Distributions menü Ebben a menüpontban a faktorokat tudjuk megvizsgálni, hogy a megfigyelések milyen arányban tartoznak az egyes szintekhez. Először kiválasztjuk a faktort (esetünkben az Ivar nevűt):
Ha nem csak azt szeretnénk látni, hogy az adatok hány százaléka tartozik ide-oda-amoda, akkor jelöljük ki a Khí-négyzet próbát:
Ebben az esetben a gép még megkérdezi, hogy mi a nullhipotézis, azaz elméletileg milyen arányban kellene ezeknek az értékeknek előfordulnia a populációban:
.Table <- table(ElsoAdatom$Ivar) .Table
# counts for Ivar
100*.Table/sum(.Table)
# percentages for Ivar
.Probs <- c(0.5,0.5) chisq.test(.Table, p=.Probs) remove(.Probs) remove(.Table)
> .Table <- table(ElsoAdatom$Ivar)
> .Table
# counts for Ivar
H N 5 6
> 100*.Table/sum(.Table)
H
# percentages for Ivar
N
45.45455 54.54545
> .Probs <- c(0.5,0.5)
> chisq.test(.Table, p=.Probs)
Chi-squared test for given probabilities
data:
.Table
X-squared = 0.0909, df = 1, p-value = 0.763
> remove(.Probs)
> remove(.Table)
Figyeljük a piros nyilakat! Az elsőnél látjuk, hány hím és nőstény volt. A másodiknál, hogy ezek milyen arányt jelentenek a mintában. A harmadik a khí-négyzet próba p-értéke. A nullhipotézis jelen esetben az volt, hogy a populációban a két csoport aránya ½-½. P=0.763>5%, azaz a nullhipotézist nem utasítjuk el. 76% a valószínűsége annak, hogy ha a populációban valóban ½-½ a nemek aránya, akkor nekünk sikerül épp így egy 11 elemű mintát választani.
Hiányzó értékek megszámolása Statistics/Summaries/Count missing observations menü Megszámolja, hogy az egyes változókban hány hiányzó érték van.
sapply(ElsoAdatom, function(x)(sum(is.na(x)))) # NA counts
> sapply(ElsoAdatom, function(x)(sum(is.na(x)))) # NA counts Glukoz
Ivar Pancreatitis
0
0
0
Nagyon rendesen kitöltöttük a táblát… A sapply() függvényt nem részleteszem.
Az adatok manipulálása Időnként szükség van arra, hogy az adatokat kicsit átalakítsuk. Ezzel kapcsolatban tanulunk meg néhány módszert a gyakorlat végén.
Gépelési hibák javítása a faktorokban Előfordulhat, hogy a faktoroknál a szintek megadásakor elgépeltünk valamit. Javítsuk ki az Ign értéket Igenre. Ezt követően kérjük le az alapadatokat. Azt tapasztaljuk, hogy az Ign szint, azaz az Ign nevű csoport még mindig létezik, csak 0 sor tartozik hozzá. Így aztán továbbra sem működnek majd azok a statisztikai próbák, amelyekhez pontosan két csoport kell. Ehhez kivételesen gépelni kell: ElsoAdatom$Pancreatitis=as.factor(as.character(ElsoAdatom$Pancreatitis)
A parancsban található látnivalók: A datasetek oszlopaira úgy tudunk hivatkozni, hogy a dataset neve után írunk egy dollárjelet, majd az oszlop nevét. (Az oszlopokat szokás változóknak is hívni.) Az egyenlőségjel nem azt jelenti, hogy a két oldalán ugyanaz a valami van, hanem azt jelenti, hogy először kiszámoljuk, hogy mi van a jobb oldalán, majd az eredményt betesszük abba a változóban, amely a bal oldalon van. Ha olyan nevű változó eddig nem létezett, akkor mostantól fog. Ha eddig is létezett, akkor az eddigi tartalmától vegyünk érzékeny búcsút. Az as.character() függvény a faktorból sima szöveget készít. Ez azt jelenti, hogy most az egyes cellákban azt a szöveget tárolja, amit beírtunk. Amíg a változónk faktor volt, addig volt valahol egy elrejtett kis táblázat, amely tudta, hogy milyen szövegek fordultak elő (mik voltak a faktor szintjei), és a változókban nem ezeket a szövegeket tárolta, hanem a táblázatbeli sorszámukat, mert így sok memóriát meg lehet takarítani. Most ez a táblázat megszűnt, a sorszámok helyére beíródtak a szövegek. Az as.factor() függvény újra létrehozza azt a kis táblázatot, de csak azokat a szövegeket teszi bele, amelyek tényleg előfordulnak. Mivel az Ign szöveg már nem szerepel sehol, ezért az nem kerül bele a táblázatba. Erre a látszólag felesleges lépésre azért van szükség, mert a statisztikai próbák egy része faktorokkal működik, szövegekkel viszont nem feltétlenül. Az utolsó látnivaló, hogy két nyitó zárójel van, de csak egy csukó! Az ablak legalján van a hibaüzenet, amit általában nem veszünk észre, csak csodálkozunk, hogy nem történik semmi hasznos.
A parancs helyesen így hangzik: ElsoAdatom$Pancreatitis=as.factor(as.character(ElsoAdatom$Pancreatitis))
Ha ismét lekérjük az alapadatokat, akkor vagy eltűnik az Ign, vagy nem. Utóbbi esetben programhiba történt, ilyenkor két lehetőségünk van: Használjuk a Data/Active data set/Refresh data set menüt. Ez általában megoldja a gondot. Ha nem, akkor még mindig van egy vészforgatókönyv: Létrehozunk egy másik datasetet tetszőleges tartalommal. Ezt követően már lehet a datasetek közül választani:
Válasszuk ki ugyanazt a datasetet, amelyet eddig használtunk, és minden működni fog.
Adatok feltételfüggő megváltoztatása Szintén gyakori eset, hogy valamelyik oszlop tartalmát meg kell változtatni bizonyos esetekben. Például a 20 feletti vércukor értékeket törölni szeretnénk, mert azokat mérési hibának véljük. (Igazi elemzésnél nem dobáljuk ki a nem tetsző adatokat, mert az hamisítás!) Ezúttal egy új változót hozunk létre a módosított adatoknak: ElsoAdatom$UjGlukoz=ifelse(ElsoAdatom$Glukoz<20,ElsoAdatom$Glukoz,NA)
Az ifelse() függvény három vektort kap paraméternek, melyek azonos hosszúságúak. Megnézi az elsőt. Ahol abban 20-nál kisebb adatot talál, ott felhasználja a Glukoz változó tartalmát. Ahol nem, oda az NA értéket írja be. Ez jelenti azt, hogy ott ismeretlen, hiányzó érték van. (Ez az egyetlen kivétel, amikor nem kell ugyanolyan hosszú vektort megadni, mint a másik kettő: amikor ugyanazt az értéket szeretnénk tenni mindenhová.) Érdemes ezek után megszámolni a hiányzó értékeket. Ha akarjuk, szöveget is lehet értéknek adni. Ebben az esetben a szöveget idézőjelbe kell tenni.
Adatok kombinálása A meglevő változókból újakat lehet létrehozni a következő nagyon egyszerű módszerrel. Az elsőbe kerüljön bele minden vércukorszint duplája: ElsoAdatom$Dupla=2*ElsoAdatom$Glukoz
Arra is van lehetőség, hogy két változó értékeit soronként összeadjuk, szorozzuk, stb. ElsoAdatom$Osszeg=ElsoAdatom$Glukoz+ElsoAdatom$Dupla*ElsoAdatom$UjGlukoz
Egy sor, egy oszlop kiírása a képernyőre Sok változót tartalmazó dataset esetén hasznos lehet, ha egyetlen változó tartalmát meg tudjuk jeleníteni. Ehhez parancsként a változó nevét adjuk meg. ElsoAdatom$Osszeg
A datasetet felfoghatjuk táblázatnak is, melynek sorai és oszlopai vannak. Például az ötödik sor harmadik oszlopában álló elem kiíratása: ElsoAdatom[5,3]
A teljes ötödik sor kiíratása: ElsoAdatom[5,]
A teljes harmadik oszlop kiíratása: ElsoAdatom[,3]
Az első, második és ötödik sor kiíratása: ElsoAdatom[c(1,2,5),]
A c() függvényt a későbbiekben gyakran használjuk. A függvénybe írt számokból vektort készít. (Jelen esetben az 1, 2 és 5 számokból egy háromelemű vektort.)
Házi feladat az első gyakorlathoz Készítsen egy új datasetet! Az első oszlop neve legyen X, tartalma 0-tól 10-ig az egész számok. Határozza meg ezen értékek átlagát, mediánját, kvantiliseit! Számolja ki ezen számok négyzetét az Y nevű változóba. Készítse el a Z változót úgy, hogy ahol az Y tartalma 50-nél nagyobb, ott az X értékét tartalmazza, egyébként az Y értékét.