R-gyak 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 parancs kiadásával.
megnyomásával, vagy a showData(ElsoAdatom)
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', maxwidth=80, maxheight=30)
font=getRcmdr('logFont'),
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. A medián olyan érték, amelynél kisebb adatok száma megegyezik a nála nagyobb adatok számával. Az 1, 2, 3, 4, 5 adatok között a medián a középső, azaz a 3. Ha páros számú adatunk van, akkor a két középső átlaga a medián. Úgy is fogalmazhatunk, hogy a nagyság szerint sorba rendezett adatokat a medián két egyenlő részre osztja, tőle balra és jobbra az adatok 50-50%-a helyezkedik el. Az alsó- és a felső kvartilis (LQ – lower quartile és UQ – upper quartile) pedig a fenti két ötven százalékot osztja két egyenlő részre. A minimum és az LQ között van az adatok 25%-a, az LQ és a medián között szintén 25%, a medián és az UQ között 25%, végül az UQ és a maximum között az utolsó 25%. Az UQ-LQ mennyiséget szokás interkvartilis terjedelemnek (IQR) nevezni.
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
Nem :5
:13.69
3rd Qu.:20.70 Max.
:23.20
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"], "quantiles"), +
statistics=c("mean",
"sd",
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):
Kicsit előreugrunk néhány héttel a tananyagban. Ezt még nem kell megjegyezni, de később jól jön majd, hogy nem akkor hallunk először az egészről. 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 szerintünk milyen arányban kellene ezeknek az értékeknek előfordulnia a populációban, ez az úgynevezett nullhipotézis:
.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 ½-½. A khínégyzet próba azt számolja ki, hogy ha ez igaz lenne, akkor mi lenne az esélye annak, hogy a mintánkban ettől az aránytól a mintában tapasztalt arány legalább ekkora eltérését tudja pusztán a véletlen mintavételezés okozni. Hagyományosan addig hiszünk a nullhipotézisben, amíg nem lesz 5% alatt annak a valószínűsége, hogy a hipotézis igaz volt, és mi mégis ilyen mintát kaptunk. Itt 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 0
Ivar Pancreatitis 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.)
Az adatok megfelelő formára hozása Az adatok tipikus elrendezése a következő szokott lenni (Excel tábla, "rossz példa" fül): Hím Egyed
1. hét
2. hét
3. hét
A
0.691
0.648
0.266
B
0.905
0.913
0.14
C
0.86
0.005 elhullott
D
0.11
0.127
0.109
E
0.536
0.934
0.51
F
0.332
0.489
0.734
Átlag
0.572333 0.519333
0.3518
Szórás
0.309946 0.390605 0.265649
Nőstény Egyed
1. hét
2. hét
3. hét
G
0.6219
0.5832
0.2394
H
0.8145
0.8217
0.126
I
0.774 elhullott
J
0.099
0.1143
0.0981
K
0.4824
0.8406
0.459
Átlag Szórás
0.55836
elhullott
0.58995 0.230625
0.258042 0.292755 0.142075
Ez az, amit soha egyetlen statisztikai program sem fog tudni értelmezni. Amit nem kellett volna: • Az átlagot és a szórást így kiszámolni. A program semmit sem tud vele kezdeni. Általában mért adatnak veszi, ezáltal teljesen hamis eredményt ad. Arról nem is beszélve, hogy a nőstényeknél biztosan jó a szórás? Természetesen semmi baj nincs azzal, ha ezeket valaki Excelben kiszámolja, de ne ugyanazon a munkalapon tegye, amelyet a statisztikai programmal meg akar etetni. • Az "elhullott" szavakat beletenni. Ha a statisztikai program bárhol szöveget talál, azt az oszlopot a továbbiakban nem tudja mérési eredményként kezelni. Ilyen esetben a cellát egyszerűen üresen kell hagyni. • Magyar ékezetes betűket és szóközöket használni. Előbbi még nem annyira vészes, ha magyar cikket tervezünk, de a szóközök mindenképp zavaróak. • A táblázat szerkezete sem felel meg a kívánalmaknak. A statisztikai program akkor tudja az adatokat feldolgozni, ha a táblázat egybefüggő oszlopokat tartalmaz. Egy oszlopban egyfajta adat van, melyet a táblázat első sora nevez meg. A táblázat sorai pedig egy-egy megfigyelést tartalmaznak, a mért értékekkel és az összes rájuk vonatkozó adattal együtt. A fenti táblázatnak helyesen így kellene kinéznie (Excel tábla "jó példa" fül): Egyed
Ivar
Het
Adat
A
male
1
0.691
B
male
1
0.905
C
male
1
0.86
D
male
1
0.11
E
male
1
0.536
F
male
1
0.332
G
female
1
0.6219
H
female
1
0.8145
I
female
1
0.774
J
female
1
0.099
K
female
1
0.4824
A
male
2
0.648
B
male
2
0.913
C
male
2
0.005
D
male
2
0.127
E
male
2
0.934
F
male
2
0.489
G
female
2
0.5832
H
female
2
0.8217
J
female
2
0.1143
K
female
2
0.8406
A
male
3
0.266
B
male
3
0.14
D
male
3
0.109
E
male
3
0.51
F
male
3
0.734
G
female
3
0.2394
H
female
3
0.126
J
female
3
0.0981
K
female
3
0.459
Majdnem minden egyedhez három sor tartozik, mert három különálló megfigyelés történt. Minden sorban látható, hogy az adott érték melyik egyedhez tartozik, az milyen ivarú, és hogy melyik héten történt a mérés. Az elhullott egyedekhez nincs sor a táblázatban. A táblázat oszlopai egy-egy tulajdonságot jelölnek.
Fontos definíciók A továbbiakban hasznos lesz az alapdolgokat a saját nevükön hívni, ha később kutatóként vagy érdeklődő hallgatóként szeretnénk szót érteni a matematikussal, mikor az adatainkat elemzi. (A nem érdeklődő hallgatóknak pedig azért kell megtanulni, hogy ne bukjanak meg a tárgyból.) Változó: Változónak nevezzük a helyesen elkészített táblázat egy oszlopát. Az első sorban van a változó neve, alatta pedig a változó értékei. Ezek vagy mért értékek, vagy a mérésre, illetve az egyedre vonatkozó információk (egyed neme, ketrec száma, mintavétel időpontja, stb.) Folytonos változó (más néven kovariáns néhány próba esetén): Olyan változó, amely egy adott tartományból tetszőleges értéket felvehet, és a lehetséges értékek között matematikai összefüggés is van. Ilyen például a vércukor, hőmérséklet. Valamit 1 fokról 2-re melegíteni ugyanazt jelenti, mint 4 fokról 5-re.
Diszkrét változó (más néven faktor néhány próba esetén): Olyan változó, amelynek a lehetséges értékei felsorolhatóak, azaz csak néhány különböző lehet belőlük. A lehetséges értékek a faktor szintjei. Ezeknek a segítségével az egyedeket jellemzően csoportokba soroljuk. Gyakran nem mért értékek, hanem az egyedre vagy a kísérletre jellemző tulajdonságok. Ezeket szövegesen is meg lehet adni (pl. hím-nőstény, kutya-macska-egér). Szöveges megadás esetén a program automatikusan faktorként értelmezi, de nagyon érzékeny az elgépelésre. Ha valamit elírunk, azt a program más csoportnak tekinti. Egy faktor szintjeit számszerűen is meg lehet adni, például kutya=1, macska=2, egér=3, de ebben az esetben nem mondhatjuk azt, hogy két kutya ér egy macskát, vagy az egér annyival nagyobb a macskánál, mint a macska a kutyánál. Vigyázni kell arra, hogy a program véletlenül se értelmezhesse folytonos változónak. Átmeneti eset: Lehetnek olyan változók, melyek bár csak néhány lehetséges értékkel rendelkeznek (pl. tojások száma egy fészekben), mégis inkább a folytonos változókra hasonlítanak, hiszen nem csoportba sorolásra szolgálnak, hanem számként viselkednek. (Van értelme arról beszélni, hogy az egyik fészekben eggyel több tojás van, mint a másikban.) Ezeket a változókat a gyakorlatban folytonosnak tekintjük.
Az adatok beolvasása Az adatainkat általában valamilyen táblázatkezelő program segítségével visszük gépre, még mielőtt a statisztikai program egyáltalán az eszünkbe jutna. Később, mikor az adataink már ott vannak egy Excel vagy OpenOffice vagy valami más táblában, valahogy nem vágyunk arra, hogy az R-be ismét begépeljük az egészet. Sokkal jobb lenne a már bevitt adatokat használni. Az R indítása után ezen a héten is a library(Rcmdr) paranccsal indítjuk a grafikus felületet. Az állományokat a Data/Import data/From Excel menüből nyitjuk meg. A jegyzethez tartozó Excel tábla különböző lapjain vannak a példaadatok. Egyelőre két adathalmazt nyissunk meg. Legyen Lepke a neve az elsőnek, mely a táblázat „jó példa” nevű munkalapja. Legyen Ver a neve a másodiknak, mely a táblázat „vérparaméter” nevű munkalapja. Az alábbi R parancsok jelennek meg a képernyőn: Lepke <- sqlQuery(channel = 1, select * from [lepke$]) Ver <- sqlQuery(channel = 2, select * from [vérparaméter$])
Az első bábok és a belőlük kifejlődött lepkék tömegét mutatja a kapott táplálék mennyisége és a környezeti hőmérséklet függvényében. A második a betegirányító rendszerből néhány kutya vérkémiai paramétereit tartalmazza. Ezekkel egyelőre nincs dolgunk. Az aktuális adathalmaz a kék feliratra kattintva változtatható meg:
A Ver nevű adathalmaz épp jó lesz gyakorolni.
Az adatok beolvasása, ha nem működik az exportálás Excelből Előfordulhat, hogy a Data/Import data/From Excel menüpont nem létezik (ha nincs Excel telepítve a gépre), vagy nem működik (például 64 bites Windows alatt). Ilyenkor kicsit csalnunk kell. Először meg kell nyitnunk az Excel állományt az Excel (vagy OpenOffice, vagy bármely egyéb táblázatkezelő) segítségével. A programból a Fájl/Mentés másként menüpontot választva mentsük el a táblázatunkat tabulátorral tagolt szöveges állományba. Sajnos ilyenkor minden munkalapot külön állományba kell menteni. Ezt követően az R-commanderben a Data/Import data/From text file menüpontot választjuk. Az ablakban a következőket állítjuk be:
Legfölül a dataset nevét, ahogyan azt a programban látni szeretnénk. Aztán a Field separatort beállítjuk Tabs-ra. Végül a Decimal-point Charactert átállítjuk vesszőre (ha magyar az operációs rendszer, különben a pont lesz a jó választás). Az OK gomb megnyomása után az állomány megnyitható.
Grafikonok rajzolása Histogram Graphs/Histogram menüpont Arra jó, hogy hisztogramot készítsünk. Normális eloszlás esetén valami haranggörbére hasonlító ábrát kellene kapnunk, mint ebben a példában is, általában erre figyelünk majd. Azt még nem tudjuk, mi az a normális eloszlás, ezért mindenféle hátsó szándék nélkül lehet gyönyörködni az elkészült grafikonokban. A hisztogramokról középiskolában már tanultunk, de gyorsan átismételjük a definíciót: Van egy folytonos változónk. Jó lenne tudni, hogy a mért értékek hol helyezkednek el sűrűbben és hol helyezkednek el ritkábban. Ennek ábrázolásához a vízszintes tengelyt egymást követő azonos hosszúságú szakaszokra (osztályintervallumokra)
osztjuk, majd megszámoljuk, hogy egy-egy intervallumba hány mérés esett. Ezt követően azzal arányos magasságú oszlopot rajzolunk az intervallumok fölé. A programban egy változót jelölhetünk ki. Ha a mező tartalmát kitöröljük és beírunk egy egész számot, akkor a hisztogramnak annyi oszlopa lesz. Általában nem kell hozzányúlni. Az
részben azt tudjuk meghatározni, hogy az y
tengelyen darabszámok vagy százalékok jelenjenek meg. A harmadik lehetőség az, amikor a gép a hisztogramot sűrűségfüggvényként jeleníti meg. Ebben az esetben az oszlopok magasságát úgy állítja be, hogy a grafikon területe 1 egység legyen.
Hist(Ver$HCO3, scale="frequency", breaks="Sturges", col="darkgray")
A scale paraméter értéke lehet „frequency”, „percent” vagy „density” a már említett három lehetőség szerint. A breaks paraméter esetén a „Sturges” helyére írhatjuk azt a számot, ahány oszlopot szeretnénk látni. Ebben az esetben nem kell idézőjel!
A grafikon színének a megváltoztatása Angolul Az előző parancsban a col paraméter határozta meg a grafikon színét. A paraméter után idézőjelben megadhatjuk egy tetszőleges szín angol nevét, majd reménykedünk benne, hogy azt a gép meg is érti. A beállítás az egész grafikonra vonatkozik. Színkóddal Másik lehetőség a színkód használata. Ilyenkor idézőjelek nélkül egy számot adunk meg a col paraméternek. Ha piros hisztogramot szeretnénk (5 oszloppal), akkor a kód:
Hist(Ver$HCO3, scale="density", breaks=5, col=2)
Az egyes színkódok jelentését a Graphs/Color palette menüben lehet megnézni. Látható, hogy 8 szín áll rendelkezésre, utána a színek az 1-estől újra kezdődnek. Egy-egy színre kattintva meg lehet változtatni, hogy milyen legyen. Szürkeárnyalattal A col=gray(x) beállítással tetszőleges szürkeárnyalatot elő tudunk állítani. Ha az x helyére 0-t írunk, feketét kapunk. Ha 1-et, akkor fehéret. Ha tetszőleges 0 és 1 közötti számot, akkor az annak megfelelő szürkeárnyalatot. Hist(Ver$HCO3, scale="density", breaks=5, col=gray(0.2))
Tetszőleges színnel Az utolsó, és egyben legnagyobb szabadságot biztosító lehetőség az rgb(piros,zöld,kék) függvény, ahol a piros, zöld és kék érték tetszőleges 0 és 1 közötti szám lehet. Gyakorlatilag végtelen sok lehetőségünk van arra, hogy horribilis összegeket költsünk a színes grafikonok publikálására. Hist(Ver$HCO3, scale="density", breaks=5, col=rgb(0.1,0.2,0.3))
A grafikon színének a megváltoztatása (egyedi oszlopok) Természetesen lehetőség van az egyedi színek megváltoztatására is. Ebben az esetben úgynevezett tömböt kell létrehozni. A tömb egy olyan „fiók”, amelynek számozott rekeszei vannak, melyek különböző adatokat tartalmazhatnak. Tömböt a c() függvénnyel hozhatunk létre. Például az a=c(1,3,5) parancs hatására az a változó a következő értékeket kapja: a[1]=1, a[2]=3, a[3]=5 Ha a grafikonunknak 5 oszlopa van, akkor célszerű a színezéskor 5 különböző színt megadni a tömb belsejében, mint azt a következő példa mutatja: Hist(Ver$HCO3, scale="density", breaks=5, col=c("red","green","blue","black","yellow"))
Számsorozat előállítása A színek megadásakor lehet kicsit trükközni. A seq() függvény segít ebben. A seq(1,10) automatikusan csinál egy tömböt, amelyben 1-től 10-ig terjedő számok lesznek szépen sorban. Ilyenkor a számok egyesével növekednek. Írhatunk a függvénybe három számot is, akkor már nem kell egész számokhoz ragaszkodni. Ilyenkor megadjuk az első számot, az utolsót és a lépésközt. A seq(0,1,0.25) a következő sorozatot állítja elő: 0, 0.25, 0.5, 0.75, 1. Ha ezt belegyógyítjuk a gray() függvénybe, akkor öt különböző szürkeárnyalatot kapunk: Hist(Ver$HCO3, scale="density", breaks=5, col=gray(seq(0,1,0.25)))
Egy icipicit tovább cifrázva lehet csinálni például piros-kék átmenetet, de ez már nem vizsgaanyag:
Hist(Ver$HCO3, scale="density", breaks=5, col=rgb(seq(0,1,0.25),0,seq(1,0,0.25)))
Számszerű adatok kinyerése a histogramból Időnként nem ártana, ha tudnánk, hogy az egyes oszlopok milyen magasak, és azt nem az ábráról kellene hunyorogva leolvasnunk. A legtöbb R függvény képes létrehozni egy objektumot, amely tartalmazza azokat az értékeket, amelyeket létrehozott vagy felhasznált. A súgó segít ezek meghatározásában. Esetünkben a Hist() függvénnyel készül a grafikon. A ?Hist paranccsal tudunk segítséget kérni:
A Description tartalmazza a függvény általános leírását. A Usage azt, hogy milyen adatokat lehet neki megadni. Az Arguments ezeket ismerteti részletesen. A Value mutatja meg, hogy milyen információkat lehet a készített objektumból kinyerni. Az Author(s) a szerzőket mutatja meg. A See Also azokat a függvényeket, amelyeknek még érdemes lehet utánanézni. Az Example pedig példákat mutat, de ezek időnként elég nehezen érthetőek. Ebből annyit lehetett kisütni, hogy ez a függvény nem készít objektumot, viszont a hist() függvényt hívja meg, amely ugyanezt csinálja, csak nem ennyire szép az ábra, amit készít. A ?hist() paranccsal tovább nézelődünk:
Ez már sokkal jobb, meg tudjuk nézni, hogy hol vannak az osztályintervallumok határai, mennyi megfigyelés van az egyes intervallumokban, mekkora az egyes oszlopok területe és mik az osztályintervallumok középpontjai. Ehhez az információhoz a következőképpen lehet hozzáférni: a hist() függvénnyel nem csak rajzolunk, hanem értéket adunk egy új változónak. Ezt követően a változó értékét kiíratjuk. Ha a változó neve mögé írunk egy dollárjelet, majd egy oszlopnevet, amely az objektumban szerepel, akkor ki tudjuk íratni csak annak a tartalmát. reszletes=hist(Ver$HCO3, scale="density", breaks=5, col=rgb(seq(0,1,0.25),0,seq(1,0,-0.25))) reszletes
> reszletes $breaks [1]
0 10 20 30 40 50
$counts [1]
5 38 25
1
1
$intensities [1] 0.007142856 0.054285714 0.035714286 0.001428571 0.001428571
$density [1] 0.007142856 0.054285714 0.035714286 0.001428571 0.001428571
$mids [1]
5 15 25 35 45
$xname [1] "Ver$HCO3"
$equidist [1] TRUE
attr(,"class") [1] "histogram"
Ha ebből csak a darabszámokra vagyunk kíváncsiak: reszletes$counts
> reszletes$counts [1]
5 38 25
1
1
Kördiagram Mielőtt nekifognánk, emlékezzünk vissza, hogyan lehet megszámolni, hány hím és hány nőstény egyed szerepelt a vizsgálatban. Használjuk a Statistics/Summaries/Frequency distributions menüpontot!
Graphs/Pie chart menü Kördiagramot már mindenki látott. Azt mutatja meg, hogy egy képzeletbeli tortából mekkora darabot hasítanak ki maguknak az egyes csoportok. A parancs, amit a program begépel helyettünk, ha az ivararányt szeretnénk szemléltetni: pie(table(Ver$Gender), labels=levels(Ver$Gender), main="Gender", col=rainbow(length(levels(Ver$Gender))))
Nyugodtan lehet szebb színeket választani, tanultuk már, hogyan kell… A table() függvényt érdemes önállóan is kipróbálni. A table(Ver$Gender) meghatároza, hogy hány megfigyelés volt a Gender oszlop egyes szintjeihez. Ha lenne egy Ver$Agegroup
nevű oszlopunk is, amely szintén faktor, akkor a table(Ver$Gender,Ver$Agegroup) parancs nemenként és korcsoportonként adná meg az esetszámokat. Megfigyelhető még a parancsban a levels() függvény, amely egy faktor szintjeinek a nevét adja meg. A szintek nevei általában ABC-sorrendben (Kicsit tudományosabban: alfabetikus sorrendben) követik egymást, de ezt a profik meg tudják változtatni. A labels paraméterrel adjuk meg a feliratokat. Jelen esetben a csoportok nevei jelennek meg. Van arra is lehetőség, hogy a név mellett megjelenítsük a darabszámokat. Ehhez a paste() függvényt fogjuk felhasználni. A függvénybe különböző szövegeket lehet beírni, melyeket szóközzel elválasztva egymás mögé ír. Kivéve, ha a függvénybe beleírjuk a sep paramétert, amellyel meghatározhatjuk, hogy a szóköz helyett mi legyen az elválasztás. Emlékszünk még, mit jelentett a „\n” szöveg? Új sort kezdett. Most már finomíthatunk kicsit az ábrán: pie(table(Ver$Gender), labels=paste(levels(Ver$Gender),table(Ver$Gender),sep="\n"), main="Gender", col=rainbow(length(levels(Ver$Gender))))
Ez a grafikon csak diszkrét változókra készíthető el.
Kördiagram fapadosan Előfordul, hogy csak egy nagyon egyszerű táblázatunk van, amelyet szeretnénk megjeleníteni, például ezt: gólya 42 veréb 28 cinege 30 Ebben az esetben a menü nem segít, de nem kell sokat gépelnünk:
pie(c(42,28,30), labels=c("gólya","veréb","cinege"), main="", col=2:4)
Oszlopgrafikon Graphs/Bar graph menü Ez a grafikon csak diszkrét változókra készíthető el, a kördiagramhoz hasonlóan. A gép összeszámolja és ábrázolja, hogy hány megfigyelés tartozott a faktor egyes szintjeihez. (Tulajdonképpen ugyanazt ábrázolja, mint a kördiagram.) Sok lehetőségünk nincs, ki kell választani egy faktort:
barplot(table(Ver$Gender), xlab="Gender", ylab="Frequency")
Boxplot Emlékezzünk vissza, hogyan lehetett megtudni a minimumot, alsó- és felső kvartilist, mediánt és maximumot! Használjuk a Statistics/Summaries/Numerical summaries menüt a kvantilisek kiírásához!
Graphs/Boxplot menü Azt lehet vele nagyon jól látni, hogy ha a mért értékeket sorba rendezzük, majd négy egyenlőrészre osztjuk, akkor hol vannak az egyes részek határai. Ha van kiugró érték (amely gyanúsan kicsi vagy nagy), azt az ábra külön megjeleníti. Általában azt szeretjük, ha az ábra szimmetrikus a doboz közepére. Egy változót lehet kijelölni, mely a példában a HB volt.
boxplot(Ver$HB, ylab="HB")
Az alsó vonal a minimum, a doboz alja az alsó kvartilis (LQ), a doboz közepe a medián, a doboz teteje a felső kvartilis (UQ), majd a maximum. Ez az elmélet, de a gyakorlatban a felső vonal a maximum alatt van. Ennek oka, hogy a tényleges maximum magasabban van, mint a doboz teteje + a doboz magasságának másfélszerese. Ez gyanúsan nagy érték, ezért a gép karikával jelöli, és maximumként azt a legnagyobb értéket adja meg, amely még a „hihető” tartományon belül van. Ebből a grafikonból is ki lehet bányászni, hogy hol is vannak pontosan az ábrán látható adatok: reszletes=boxplot(Ver$HB, ylab="HB") reszletes$stats
> reszletes$stats [,1] [1,] 0.0950 [2,] 0.3360 [3,] 0.4175 [4,] 0.4980 [5,] 0.7060
Arra is lehetőség van, hogy egymás mellett több csoport adatait is megjelenítsük. Ehhez a gombra van szükségünk. Az eredmény:
Ilyen esetben némi sejtésünk lehet arról, hogy a két csoportban megegyezik-e az átlag. Ha a két doboz között átfedés van, akkor ritkán van szignifikáns (azaz statisztikai módszerekkel
bizonyítható) különbség a két csoport átlaga között. Ha a két doboz között nincs átfedés, akkor inkább a szignifikáns különbség a jellemző. Kiugró értékek Mint láttuk, volt egy olyan érték, amely nem volt benne a „hihető” tartományban. Ez egy úgynevezett kiugró érték (outlier) volt. Ilyen három ok miatt szokott előfordulni: •
Van egy vagy több olyan egyed, amely például nagyon beteg, ezért valamelyik vizsgálat eredménye nagyon eltér az egészséges vagy enyhén beteg egyedeknél mérhetőtől. Ilyenkor a kiugró értéket megtartjuk.
•
A mérésnél vélhetően hiba történt. Elképzelhetetlen, hogy egy egyednél valóban azt az értéket mérjük. Ilyenkor a kiugró értéket elhagyjuk. Ez egy nagyon érzékeny szakmai döntés, melynek eredménye könnyen az lehet, hogy adathamisítással vádolnak meg minket. Ezért ilyen esetben a cikkben, előadásban mindig jelezni kell, hogy milyen adatokat zártunk ki, és ennek mi volt az oka.
•
Az is előfordulhat, hogy ha kizárjuk a kiugró értékeket, akkor addig „normális” adatok válnak kiugróvá. Ha azokat is töröljük, akkor ismét ugyanez történik. Ebben az esetben nem szabad adatokat kizárni, mert nem hibás értékről, hanem úgynevezett ferde eloszlásról van szó. Erről majd később tanulunk.
Adathalmaz mentése Előfordulhat, hogy az adatokat módosítanunk kellett. Például létrehoztunk egy új változót (oszlopot), mely két csoportba („korai” és „késői”) sorolja a kutyákat az alapján, hogy az azonosítójuk (ID oszlop) kisebb-e 13802-nél. Ver$Group=ifelse(Ver$ID<13802,”korai”,”kesoi”)
Ezt követően az adathalmazt elmenthetjük az R saját formátumába a Data/Active dataset/Save active dataset… menüben.
Ez az, amit az R-en kívül semmi nem fog tudni utána beolvasni, mert saját formátumot használ. Az R-ben a Data/Load dataset menüben tudjuk az adatokat visszavarázsolni a memóriába.
Adathalmaz mentése 2 Ha olyan formában szeretnénk az adatainkat menteni, amely más programmal is beolvasható, akkor a Data/Active data set/Export active data set… menüpontot választjuk. Az így létrehozott állomány szövegszerkesztővel olvasható, Excelben is megnyitható, de a használatát itt nem részletezzük. Bonyolultabb a használata, és több a hibalehetőség, mint egy Excel tábla megnyitásakor.
Scatterplot Graphs/Scatterplot menü Azt tudjuk vizuálisan ellenőrizni, hogy ha az egyik folytonos változó értéke magasabb, akkor jellemző-e az, hogy egy másik folytonos változó értéke vele együtt változik (nő vagy csökken). Ezt majd később korrelációnak hívjuk, ha eljön az ideje. Először kiválasztjuk a változókat az x és az y tengelyre:
Néha nem ért transzformálni az x vagy az y tengelyt (esetleg mindkettőt):
A transzformálással azt érhetjük el, hogy az ábrán a pontok a korábbi görbe vonal helyett egy egyenesbe esnek. Néhány statisztikai módszer ezt nagyon szereti. Később látunk majd erre példákat. A boxplot és a trendvonalak nem ártanak, általában nem kapcsoljuk ki őket:
Ennél a grafikonnál kivételesen már itt megadhatjuk az x és az y tengely nevét:
Végezetül lehet különböző színnel ábrázoltatni a különböző csoportokat. Én most beállítom, hogy a hímeket és a nőstényeket különböztesse meg. Van még néhány beállítási lehetőség az ablakban, azokkal nyugodtan lehet kísérletezni.
scatterplot(HCO3~HB | Gender, reg.line=lm, smooth=TRUE, labels=FALSE, boxplots='xy', span=0.5, by.groups=TRUE, data=Ver)
Erről az ábráról a következőket lehet leolvasni: • A HB növekedésével a HCO3 növekedni látszik. A piros és zöld szaggatott vonal emelkedik. o Vigyázat! Ezt az ábra önmagában nem bizonyítja, ahhoz hipotézisvizsgálat kell! o Vigyázat! Ha az összefüggés fennáll, akkor sem jelent ok-okozati összefüggést! • A két nem esetén nem várható lényeges különbség, a két szaggatott vonal szinte párhuzamos. • A kapcsolat nem túl szoros, a pontok elég messze is tudnak lenni a szaggatott vonaltól. • Ha a két folytonos vonal hasonlóan nézne ki, akkor azt gyanítanánk (mondjuk a pirosat alapul véve), hogy nagyjából 0.5-ös HB-ig a HCO3 növekszik, aztán csökken. Ilyenkor nem lehetne lineáris regressziót használni. Mivel a zöld vonal egész másként néz ki, és nem feltételezem, hogy ez az összefüggés neme k szerint eltérő lenne, arra szavazok, hogy jó lesz nekem a lineáris összefüggés, azaz a szaggatott vonal.