Rakendustarkvara: R
7. praktikum1
7. praktikum1
1 Andmetöötlus paketiga dplyr
Pakett dplyr mõeldud andmetabelite täienduste, tabelis olevate objektide või tunnuste alamhulkade valiku, grupeerimise ja sorteerimise teostamiseks. Samuti saab selle abil leida erinevaid andmeid agregeerivaid tabeleid, mis sobivad kirjeldava statistilise analüüsi läbiviimiseks. Paketi dplyr käskude juures võib välja tuua veel nende töö kiiruse suuremate andmestike korral. Põhjalik ülevaade selle paketi käskudest on paketi dokumentatsioonis2. Põhifunktsioonid paketis on järgmised
mutate()
– lisab andmestikku uusi tunnuseid, mis on leitud olemasolevate põhjal.select()
– valib andmestikust nime põhjal tunnused.filter()
– valib andmestikust vaatlused/read loogilise tingimuse põhjal.summarise()
– summaarsete näitajate leidmine.arrange()
– andmestiku ridade sorteerimine.
Kõigi funktsioonide esimene argument on andmetabel, järgmised argumendid täpsustavad, mida andmestikuga teha tuues ära tunnuste nimed, mille kirjapanekuks siin käskudes jutumärke pole vaja kasutada. Kõik funktsioonid väljastavad tulemuseks omakorda andmetabeli. Kõiki funktsioone saab kombineerida käsuga group_by()
, mis määrab toimingute tegemise gruppide kaupa.
1.1 Paketi dplyr käskude kasutamine
Loeme kõigepealt sisse näiteandmestiku: Massachusettsi valikuuring
mass <- read.table("https://github.com/Rkursus/2021/raw/master/data/mass.txt", sep = "\t", header = T)
Paketi installimine ja aktiveerimine:
#install.packages(dplyr) # vajadusel installeerida pakett
library(dplyr)
Käsu mutate()
abil saab andmestiku veergudega teisendusi teha, uusi tunnuseid tekitada või ka mingeid tunnuseid kustutada
# arvutame kaks uut tunnust, kustutame ühe vana
mass1 <- mutate(mass,
kuus = WAGP/12,
kuus_euro = kuus * 0.8,
MIG = NULL)
Käsk filter(.)
aitab valida välja teatud kriteeriumitele vastavaid ridu. See on kiirem kui kantsulgude kasutamine, sest kantsulgusid kasutades vaadatakse üksikud elemendid ükshaaval üle, ent filter(.)
käsu puhul kasutatakse nutikamaid algoritme (enamasti andmed sorditakse mingil moel enne kui hakatakse üldse filtris määratud kriteeriumeid kontrollima).
# rakendame filtrit (ekraanile paari esimese veeru väärtused neil vaatlustel)
filter(mass, AGEP > 70, WAGP > 100000)[,1:3]
## id AGEP CIT
## 935 9452 84 U.S. citizen by naturalization
## 4900 49277 71 Born in the U.S.
## 6374 64546 77 Born in the U.S.
Käsu select(.)
abil saab välja valida tingimustele vastavaid veerge andmestikust. Järgmises näites on rakendatud esmalt ridade filtreerimist, seejärel tehtud valik veergude hulgast: valitakse need veerud, mille nimes sisaldub täht “G”
# rakendame filtrit ja selekteerime tunnuseid
select(filter(mass, AGEP > 70, WAGP > 100000), contains("G"))
## AGEP MIG WAGP
## 935 84 No, different house in US or Puerto Rico 150000
## 4900 71 Yes, same house (nonmovers) 110000
## 6374 77 Yes, same house (nonmovers) 145000
Käsk group_by(.)
aitab andmestiku tükkideks jagada, aga ei tee sellega midagi enamat. Kui tükkidel soovida midagi analüüsida, tuleb group_by(.)
funktsiooni tulemus ette anda vastavaks analüüsiks kasutatavale funktsioonile. Siin kohal on hea kasutada funktsiooni summarise(.)
, mis esitab agregeeritud tulemused:
summarise(group_by(mass, CIT),
keskpalk = mean(WAGP, na.rm = T),
n = n(),
notNA = sum(!is.na(WAGP)))
## # A tibble: 5 x 4
## CIT keskpalk n notNA
## <chr> <dbl> <int> <int>
## 1 Born abroad of American parent(s) 28589. 62 51
## 2 Born in Puerto Rico, Guam, the U.S. Virgin Islands, 12516. 79 74
## 3 Born in the U.S. 33829. 5422 4361
## 4 Not a citizen of the U.S. 32797. 448 423
## 5 U.S. citizen by naturalization 30703. 413 404
Käsu arrange(.)
abil saab andmestikke sorteerida
osa <- filter(select(mass, id, SEX, AGEP, WKHP, WAGP), WAGP > 300000, AGEP < 55)
arrange(osa, SEX, desc(AGEP), WKHP)
## id SEX AGEP WKHP WAGP
## 393 4026 Female 53 50 502000
## 4716 47523 Female 44 45 502000
## 5427 54710 Female 38 30 502000
## 5654 56856 Male 54 65 502000
## 4468 45001 Male 52 60 502000
## 2595 26473 Male 51 60 502000
## 2666 27055 Male 50 60 502000
## 5115 51654 Male 49 60 502000
## 6327 63966 Male 48 48 502000
## 4195 42026 Male 45 40 502000
## 4860 48820 Male 45 40 502000
## 1254 12981 Male 45 55 502000
## 4697 47379 Male 45 60 502000
## 4809 48414 Male 45 70 502000
## 77 821 Male 42 50 502000
## 1182 12187 Male 40 50 502000
## 2689 27263 Male 40 60 502000
## 3782 38114 Male 39 50 502000
## 6178 62255 Male 37 60 502000
## 4191 41999 Male 34 60 502000
## 5989 60364 Male 32 55 502000
## 5950 59973 Male 29 85 502000
Lisaks on paketis dplyr defineeritud toru ehk aheldamisoperaator (kujul %>%
), millega on võimalik ühe funktsiooni tulemused edasi anda järgmisele funktsioonile, ilma, et vahetulemust ekraanile prinditaks või uuele muutujale omistataks. Ehk koodi, kus on vaja rakenda kahte funktsiooni fun1
ja fun2
järgmiselt fun2(fun1(x), y)
võib kirja panna kujul fun1(x) %>% fun2(y)
. Esimese funktsiooni tulemus antakse siin teisele funktsioonile ette esimeseks argumendiks.
Toru kasutamine aitab mõnikord muuda koodi loetavamaks. Näiteks, kui on vaja leida andmestikust mass
soo ja perekonnaseisu gruppides keskmist palka ning grupi mahtu ja saadud tulemustabelist näha esimesi ridu, siis aheldamisoperaatori abil saaks selle kirja panna järgmiselt:
mass %>%
group_by(SEX, MAR) %>%
summarise(keskpalk = mean(WAGP, na.rm = T), n = n()) %>%
head()
## `summarise()` has grouped output by 'SEX'. You can override using the `.groups` argument.
## # A tibble: 6 x 4
## # Groups: SEX [2]
## SEX MAR keskpalk n
## <chr> <chr> <dbl> <int>
## 1 Female Divorced 33860 281
## 2 Female Married 28164. 1356
## 3 Female Never married or under 15 years old 21621. 1336
## 4 Female Separated 19476. 54
## 5 Female Widowed 4233. 272
## 6 Male Divorced 39444. 187
Kui paneksime sama asja kirja “tavaliselt”, siis peaksime koodirida alustama nö tagantpoolt ettepoole ehk alustama viimasest operatsioonist, mida andmetele rakendada (head
)
head(summarise(group_by(mass, SEX, MAR), keskpalk = mean(WAGP, na.rm = T), n = n()))
1.1.1 Ülesanded
Leia inimeste vanuses 16 aastat kuni 85 (kaasaarvatud) aastat, keskmine ja maksimaalne nädala töötundide arv (WKHP), soo ja vanusgruppide (5-aastased vanusgrupid) kaupa. Esita tabelis ka gruppide mahud ja vaatluste arv, mida on keskväärtuse/maksimumi leidmisel kasutatud. Leia küsitud tabel kahte moodi, nii “toru” kasutades kui ilma.
Tee eelmise ülesande andmete põhjal joondiagramm.
Aheldamisoperaatorit kasutades ühenda eelmised kaks ülesannet.
2 Pakett data.table
Suurte andmete filtreerimiseks, teisendamiseks, agregeerimiseks ja grupeerimiseks sobib ka pakett data.table3.
Paketi andmetabel ehk data.table on tavalise andmetabeli data.frame-i edasiarendus. Nagu tavalise andmetabeli korral on data.table tabelist võimalik objekte ja veerge valida kantsulgudes indekseid määrates. Lisavõimalus on see, et data.table tabelis saab sel moel uusi tunnuseid arvutada, tunnuseid jooksvalt uuendada ning andmeid grupitunnuse põhjal agregeerida.
Kui DT
on data.table tüüpi andmetabel, siis põhisüntaksi kuju saab kirja panna järgnevalt
DT[i, j, by]
kus
i
määrab read/objektid, mida edasi kasutadaj
määrab veerud, mis valitakse, uuendatakse või tekitatakseby
määrab vajadusel grupitunnusej
tehtavateks arvutustesse.
2.1 Näited data.table süntaksi kasutamisest
Siinkohal mõned näiteid andmestikust objektide või veergude valimisest ja arvutuste kirjapanekust. Proovi need läbi ja uuri tulemust. Erinevalt tavalisest andmestikust ei ole data.table tabelites reanimesid, on ainult reanumbrid, seega rida nime järgi valida saa. Teiseks võib välja tuua, et tekstitunnused on neis tabelites vaikimisi character tüüpi, mitte factor tüüpi.
#install.packages("data.table") # vajadusel installeerida
library(data.table)
# data.table tüüpi objekti moodustamine
DT <- data.table(a = 1:10,
b = rep(1:3, c(3, 3, 4)),
c = rep(LETTERS[5:7], c(4, 3, 3)))
DT
## a b c
## 1: 1 1 E
## 2: 2 1 E
## 3: 3 1 E
## 4: 4 2 E
## 5: 5 2 F
## 6: 6 2 F
## 7: 7 3 F
## 8: 8 3 G
## 9: 9 3 G
## 10: 10 3 G
str(DT)
## Classes 'data.table' and 'data.frame': 10 obs. of 3 variables:
## $ a: int 1 2 3 4 5 6 7 8 9 10
## $ b: int 1 1 1 2 2 2 3 3 3 3
## $ c: chr "E" "E" "E" "E" ...
## - attr(*, ".internal.selfref")=<externalptr>
Ridade ja veergude valik (alamosa andmetabelist)
DT[1:2, ]
DT[b > 1.5, ]
DT[, 3]
DT[, a]
DT[,"a"]
DT[b > 1.5, 3]
DT[c(1, 3:4), .(a, b)]
DT[.N,]
Uue tabeli moodustamine, arvkarakteristikud, loendamine, uued tunnused:
DT[, .(kv = mean(a), s = sd(a), mitu = .N), by = c]
DT[a > 3, .N]
DT[, .N, by = c]
DT[, .(d = a + 50)]
Olemasoleva tabeli sees muudatuste tegemine. Lisatud tühjad kantsulud []
rea lõpus prindivad muudetud tabeli DT
ekraaanile. Üldjuhul neid lisama ei pea.
# ühe uue tunnuse lisamine
DT[, d := a + 5][]
# mitme uue tunnuse lisamine
DT[, c("uus1", "uus2") := .(a + 5, b - 2) ][]
# mitme uue tunnuse lisamine, variant 2
DT[, `:=` (uus3 = a + 50,
uus4 = b - 2,
b = -b)][]
# väärtuste muudatus valitud ridades
DT[c(2, 4), a := a*10L][]
# uus tunnus, aga mitte igas reas
DT[c(2, 4), uus5 := a*10L][]
# tunnuste kustutamine
DT[, uus5 := NULL][]
DT[, c("uus1", "uus2") := NULL][]
2.1.1 Ülesanded
- Teisenda andmestik
mass
paketi data.table andmetüübiks käsugaas.data.table(.)
. - Kasutades
DT[i, j, by]
konstruktsiooni leia mitu meessoost üle 60 aastast on uuritavate hulgas. - Kasutades
DT[i, j, by]
konstruktsiooni leia perekonnaseisu sagedustabel. - Järjesta eelmine tabel sageduste järgi kasvavalt.
- Täienda eelmist tabelit gruppide osakaaludega.
- Tekita tabel, kus oleks soo ja perekonnaseisu gruppides leitud keskmine vanus, vanuse standardhälve ja levinum haridustase.
Praktikumijuhendid põhinevad aine MTMS.01.092 Rakendustarkvara: R (2 EAP) materjalidel, mille autorid on Mait Raag ning Raivo Kolde↩︎
https://cran.rstudio.com/web/packages/dplyr/vignettes/dplyr.html↩︎
https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html↩︎