Adattudomány

Az adattudomány (data science) jelentősége az adatmennyiség exponenciális növekedésével egyre jelentősebb. Ezen az oldalon összefoglalom a legfontosabb tudnivalókat. Az anyag az ingyenesen elvégezhető 10 részes https://www.coursera.org/specializations/jhu-data-science kurzus sorozatra épül; a fejezetcímek egyben az ottani kurzuscímek is. A tananyag szabadon elérhető itt: https://github.com/bcaffo/courses/. Az egyes kurzusok az alábbi linkeken érhetőek el:

Fontos megjegyzés: nem tartom maga adattudósnak; szoftverfejlesztő vagyok, és az adattudománnyal a PhD-m során kerültem kapcsolatba. Ez az oldal leginkább emlékeztető kivonat magamnak, de lehet, hogy másnak is hasznos, és esetleg kedvet kap a fenti kurzusok elvégzéséhez. A leírás bevezető jellegű, így azok a részeket kimaradnak belőle, amelyeket nem tartok fontosnak.

Az adattudós eszköztára

Kurzus: https://www.coursera.org/learn/data-scientists-tools/

Legfontosabb eszközök (mind ingyenes); ezeket töltsük le ill. regisztráljunk:

  • R statisztikai rendszer: R projekt (ez maga az R rendszer), R Studio (fejlesztői környezet), R tools (eszközök R csomagok készítéséhez). Az R mellett a Markdown jelölőnyelvek (markup language) is érdemes megismerni, melynek egy jó összefoglalója található itt: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet.
  • Git verziókövető rendszer: Git (ez maga a verziókövető szoftver), GitHub (repó, ahova a Git projekteket menthetjük). A git parancsok és a GitHub használata mellett szükség van alapvető parancssori ismeretekre is.

Az adattudomány kérdéseinek típusai:

  • Leíró (descriptive): egy adathalmaz leírása.
  • Felderítő (exploratory): korábban nem ismert kapcsolat felderítése.
  • Következtető (inferential): állítás megfogalmazása nagyobb adatmennyiségről viszonylag kis minta felhasználásával.
  • Előrejelző (predictive): valamilyen dologgal kapcsolatos adatok felhasználása más dologgal kapcsolatos értékek előrejelzésére.
  • Alkalmi (?) (casual): annak a kiderítése, hogy mi történik egy változóval ha egy másikat megváltoztatunk.
  • Mechanisztikus (?) (mechanistic): egy változó megváltozásának megértése, amely más dolgok változóinak a megváltozásához vezetnek.

Az adattudományban a legfontosabb a kérdés, a második legfontosabb az adat.

R programozás

Kurzus: https://www.coursera.org/learn/r-programming

Az R egy ingyenes, statisztikai célú programozási nyelv. A (fizetős) S rendszerre épül. Erejét az ingyenessége mellett a több ezer, ugyancsak ingyen elérhető csomag adja. Megjegyzés: ebbe a részbe nemcsak az itt elhangzottakat veszem fel, hanem olyan részeket is, melyek a sorozat más kurzusán hangzottak el, de lényegében az R szintaxis témához tartozik.

Bevezető

Néhány alapvető információ az R-ről:

  • Van neki parancssoros interfésze, melynek segítségével közvetlenül adhatunk ki parancsokat, amelyeket azonnal végrehajt. Ha elindítjuk az R keretrendszert vagy az R studio-t, akkor parancssori utasításokat adhatunk ki.
  • Valamint a programokat szövegfájlokba is írhatjuk és futtathatjuk. A szokásos kiterjesztés: .R. Futtatás: R —slave —vanilla < filename.R
  • Csomagok telepítése: install.packages, pl. install.packages("devtools"). Csomag beolvasás: library, pl. package(devtools).
  • Segítség: ? (pl. ?max), vignette() (pl. vignette("intro")), library(help = "datasets").
  • Az R-ben nem kell megadni a változó típusát.
  • A szokásos értékadás jele <- (pl. x <- 5), de az = jel is működik.
  • Az utasításokat ;-vel választhatjuk el, de nem kötelező a használata.
  • Megjegyzés: #
  • Kiírás: lehet implicit, amikor megadjuk a kiírandó változó nevét (pl. x), vagy explicit a print utasítással (pl. print(x)).

Adattípusok

Az R-ben az adattípusok filozófiai megközelítésben és megvalósulásában is eltérnek a más programozási nyelvekben megszokottaktól. Mivel ebben a rendszerben adatokkal dolgozunk, különösen fontos az adattípusok megértése.

  • Atomi adattípusok:
    • szöveges (character)
    • valós szám (numeric)
    • egész szám (integer)
    • komplex (complex)
    • logikai (logical)
  • Összetett adattípusok:
    • vektor (vector)
    • mátrix (matrix)
    • lista (list)
    • faktor (factor)
    • adat keret (data frame)

Általános tudnivalók:

  • Egy szám típusa alapból valós; az L posztfixet kell hozzáírni, ha egészként szeretnénk tárolni (pl. x <- 5L).
  • A számoknál létezik végtelen (pl. 1/0=Inf), nem kiszámolható (pl. 0/0=NaN).
  • A hiányzó adat a NA.
  • A szöveges típust aposztrof jelek és idézőjelek közé is tehetjük (pl. 'hello', "hello").
  • A logikai értékek: TRUE és FALSE.
  • Az adat típusát a class() függvény segítségével tudhatjuk meg (pl. class(x)).
  • Az összetett adatoknak lehetnek attribútumaik, melyet az attributes() függvény segítségével tudunk lekérdezni (pl. ha m egy mátrix, akkor attributes(m)).
  • Az adatok egymásba konvertálhatóak az as.*() függvények segítségével (pl. as.numeric(x), as.logical(x), as.character(x)).

Vektor:

  • A legelemibb adattípus.
  • A vektor ugyanolyan osztályú elemek listája.
  • Létrehozási lehetőségek:
    • Alapból mindegyik elem egy egyelemű vektor, pl. az x <- 5 hatására az x egy egyelemű vektor lesz.
    • A : operátorral, pl. a 1:5 eredménye a következő 5 elemű vektor: 1 2 3 4 5.
    • A c (concatenate, összefűzés) függvénnyel, pl. a v <- c(1, 5, 3:9) az 1 5 3 4 5 6 7 8 9 vektort hozza létre.
    • Értékadás nélküli vektort a vector() függvénnyel hozhatunk létre, pl. a vector(length = 5, mode = "numeric") eredménye ez: [1] 0 0 0 0 0.
  • Az R-ben a legtöbb művelet vektorizált, ami azt jelenti, hogy mindegyik elemre végrehajtja. Pl. az 1:4 + 2*(5:8) eredménye ez lesz: [1] 11 14 17 20.

Mátrix:

  • A mátrix valójában vektor dimenzió (dim) attribútummal. A dimenzió attribútum egy 2 elemű vektor.
  • Mivel a mátrix is vektor, csak egyfajta elemet tartalmazhat.
  • Mátrixot a matrix() függvénnyel tudunk létrehozni, ahol megadhatjuk az adatokat oszloponként, majd a nrow és ncol paraméterekkel a mátrix dimenzióit adhatjuk meg. Példa: m <- matrix(1:12, nrow = 4, ncol = 3).
  • A utólag is mátrixot átméretezhetjük azzal, hogy a dim attribútumot átállítjuk.
  • Oszlopot a cbind(), míg sor az rbind() függvénnyel adhatunk hozzá.
  • Az egyes soroknak ill. oszlopoknak nevet is adhatunk a dimnames() függvény segítségével.

Lista:

  • Olyan vektor, amely különböző típusú adatokat tartalmazhat, pl l <- list(5, "alma", TRUE).
  • Elem címzése: [[index]] (ha úgy címezzük mint a vektort ([index]), akkor egy egyelemű listát kapunk).
  • Nevet is adhatunk az elemeknek, és akkor $ jellel hivatkozhatunk rá, pl. l <- list(szam=5, gyumolcs="alma", finom=TRUE), majd l$gyumolcs.

Faktor:

  • Adatkategóriákat lehet vele létrehozni.
  • Létrehozó függvény: factor(), pl. f <- factor(c("igen", "igen", "nem", "igen", "nem")).
  • Sorrend átrendezése: relevel(), pl. f2 <- relevel(f, "nem").

Adatkeret (data frame):

  • Adatok táblázatos elrendezésére szolgál (kb. mint egy adattábla az adatbázisban).
  • A mátrixszal ellentétben különböző típusokat tartalmazhat.
  • Reprezentáció: ezek valójában speciális listák, mégpedig a lista mindegyik eleme egy ugyanolyan hosszú vektor.
  • A lista egy eleme felfogható oszlopként.
  • A listák hossza a sorok száma.
  • Oszlopok nevei: row.names attribútumok.
  • Létrehozása: data.frame() függvénnyel, pl. df <- data.frame(szam=c(2, 3, 2, 3, 5), gyumolcs=c("alma", "banan", "alma", "barack", "banan")), valamint tipikusan beolvasásokkal (read.table()).

Műveletek

  • Matematikai műveletek
    • abs(x) - abszolút érték
    • sqrt(x) - négyzetgyök
    • sin(x), cos(x), tan(x), asin(x), … - trigonometrikus függvények
    • log(x), log2(x), log10(x) - logaritmus
    • exp(x) - exponenciális
  • Kerekítések
    • ceiling(x) - felfelé kerekítés
    • floor(x) - lefelé kerekítés
    • round(x, digits=n) - adott tizedespontig kerekít, a kerekítési szabályok szerint
    • signif(x, digits=n) - adott értékes jegyig kerekít
  • Halmaz műveletek
    • intersect(x, y) - metszet
  • Logikai műveletek
    • %in% - azt vizsgálja, hogy benne van-e egy elem a halmazban, pl. table(df$gyumolcs %in% c("alma", "barack"))

** String műveletek**
* tolower(), toupper() - kisbetűsítés, nagybetűsítés
* strsplit() - szöveg felosztása
* sub(), gsub() - csere (első ill. az összes)
* grep(), grepl() - mintaillesztés (szöveget ill. logikai értéket ad vissza)
* nchar() - karakterek száma
* substr() - rész szöveg
* paste, paste0 - összefűzés (szóközzel, szóköz nélkül)
* library(stringr): str_trim() - szóköz karakterek eltávolítása a végekről

Példa adatok

A datasets csomagban találhatóak előre csomagolt adatok:

  • airquality - légminőségi adatok 1973-ból (154 megfigyelés, 6 változó)
  • mtcars - autó adatok 1974-ből (32 megfigyelés, 11 változó)
  • swiss - szociológiai adatok Svájc francia részéről, 1888-ból (47 megfigyelés, 6 változó)

Adatok generálása

  • seq() - szekvenciák létrehozása, pl. seq(1, 9, by=2) (kettesével), seq(1, 9, length=3) (az eredmény hossza van megadva).
  • ifelse() - bináris változó létrehozása, pl. ifelse(1:9 < 5, TRUE, FALSE).
  • cut() - kategorikus változók létrehozása; az egyes elemeket átalakítja a tartalmazó intervallumokká, pl. cut(1:10, breaks=c(0, 3, 7, 10)). Másik lehetőség (egyszerűbb paraméterezéssel): a Hmisc könyvtárban található cut2() függvény.

Adatok összefoglalása

Az R-ben tipikusan rengeteg adattal dolgozunk, melynek teljes áttekintése nem könnyű feladat. Az alábbi függvények gyors, de nem részletes áttekintést tesznek lehetővé:

  • head(), tail() - az első ill. utolsó pár adatot tudjuk megjeleníteni (pl. egy hosszú szöveg vagy nagy adatkeret első vagy utolsó néhány sorát).
  • summary() - adattípustól függő összegzést készít, pl. summary(df).
  • str() - az adatok struktúráját adja vissza.
  • names() - az elnevezéseket adja vissza, pl. ad adatkeretek oszlopneveit.
  • quantile() - a paraméterül átadott értékek legfontosabb kvantilisait (legkisebb elem, 25%, medián, 75%, legnagyobb elem) adja vissza (beállítható).
  • table() - táblázatot készít. Ha pl. egy nagy adatkeret két oszlopát adjuk paraméterül, akkor a táblázat egy cellája azt mutatja meg, hogy adott kombinációval hány elem fordul elő. Ha egy vektort adunk át, akkor megmutatja, hogy melyik elem hányszor fordul elő.
  • xtabs() - tartalmazás táblát készít, de komplexebb eseteket is képes kezelni. Pl. (xtabs(~szam+gyumolcs, df))
  • rowSums(), colSums(): soronkénti ill. oszloponkénti összegzés, pl. rowSums(m)
  • object.size() - az objektum bájtban kifejezett méretét adja vissza.

Adatok átalakítása

  • Részhalmazok képzése
    • A [] eredményének típusa mindig megegyezik az eredetiével. Ezzel több elemet is kiválaszthatunk. Pl. v[5], v[c(2, 4:7)]
    • A [[]] segítségével listák és adatkeretek elemeit lehet megcímezni. Az eredményének a típusa nem feltétlenül egyezik meg az eredetiével, és ezzel csak egy elemet választhatunk ki. Példa: l[[2]]
    • A $ név szerint választ elemet listából és adatkeretből; működése hasonló a [[]]-hez. Különbség: a [[]] esetében használhatunk kiszámolt változót (tehát ha pl. az oszlopnevet változóból vesszük, pl. elemnev <- "gyumolcs"; l[[elemnev]]), míg $ esetén csak literál nevet használhatunk. Példa: l$gyumolcs
    • A [[]] és $ esetén a mintaillesztés megengedett, pl. l$gy.
    • A részhalmazt képezhetjük indexekkel (pl. v[1:4] a v vektor első 4 elemét választja ki) vagy logikai műveletekkel (pl. az v[v>5] az 5-nél nagyobb elemeket választja ki).
    • Mátrixok esetében a címzésnél kiválaszthatunk egy elemet (pl. m[1,2]), képezhetünk részmátrixot (pl. m[c(2:4), c(1, 3)]), elhagyhatjuk a sor vagy oszlop kiválasztást (pl. m[1,], m[,2]). Ha az eredmény lehet vektor, akkor az R vektorrá konvertálja (ki lehet kapcsolni a drop=FALSE kapcsolóval).
    • Adatkeretekből a mátrixhoz hasonlóan választhatunk ki elemeket, sorokat, oszlopokat, rész adatkereteket. Az oszlopokra hivatkozhatunk névvel vagy sorszámmal. A listáknál bemutatott [], [[]] és $név kiválasztás is működik.
    • A kiválasztásnál logikai műveletek is megadhatóak, pl. df[df$szam < 3 | df$gyumolcs=="banan",]. Hiányzó adat lekérdezése: is.na(). Ha a feltételt a which() függvénybe tesszük, akkor a kiértékelésnél kiszűri az NA adatokat.
  • Sorba rendezés
    • sort() - rendezés, pl. sort(v).
    • order() - a rendezésutáni sorszámát adja vissza. Pl. a fenti adatkeret szám szerinti sorba rendezése: df[order(df$szam),]. Több oszlop szerint is rendezhetünk.
  • Kiegészítés
    • Oszlop hozzáadása adatkerethez: pl. df$veletlen <- rnorm(5).
    • cbind() - oszlop hozzáadása mátrixhoz vagy adatkerethez, pl. cbind(m, 1:4).
    • rbind() - sor hozzáadása, pl. rbind(m, 1:3) (szintén nem marad része).
  • Átalakítás
    • ftable() - "lapos" tartalmazási táblázatot készít. Ha az adatkeret két oszlopot tartalmaz, akkor az eredmény megegyezik a fentiekkel, ha viszont többet, akkor legenerálja az összes kombinációt. (Így sok oszlop és nagy táblázat esetén az eredmény áttekinthetetlen lesz.)
    • library(reshape2), melt() - adatok "feloldása" oly módon, hogy kettő vagy több oszlop megszűnik, létrejön egy új variable és value oszlop, a variable az eredeti oszlop nevét tartalmazza, a value pedig az értékét. Így az oszlopok száma csökkenhet, a sorok száma nőni fog. Vonatkozó függvény: cast().
    • library(plyr), arrange() - sorba rendezés, pl. arrange(df, szam), arrange(df, desc(szam)).
    • library(plyr), mutate() - adatkeret átalakítása, pl. oszlop hozzáadása.
    • library(plyr), ddply() - adatkeret felosztása, művelet végrehajtása, az eredmény visszaadása adatkeret formában.
  • Összefűzés
    • merge() - kettő adatkeret összefűzése közös oszlopnév alapján.
    • library(plyr), join() - ez is ugyanezt a műveletet hajtja végre.
    • library(plyr), join_all() - több adatkeret összefűzése

Adatok írása-olvasása

  • Fájl műveletek:
    • getwd(), setwd("könyvtárnév") - a munkakönyvtár lekérdezése, beállítása
    • file.exists("könyvtárnév") - annak ellenőrzése, hogy létezik-e a fájl vagy könyvtár
    • dir.create("könyvtárnév") - könyvtár létrehozása
    • list.files("könyvtárnév") - adott könyvtárban található fájlok kilistázása
    • download.file("fájlnév") - fájl letöltése az internetről
  • Szerializálás:
    • Egy objektum szerializálása: dput(), melynek a párja dget(). Pl. dput(fruits, file="fruits.R"), majd fruits2 <- dget("fruits.R").
    • Több objektum szerializálása: dump(), melynek a párja source(). A szintaxis hasonló mint a fenti.
  • Fájl műveletek:
    • readLines() - sorok beolvasása szövegből
    • Lehetőségek: file(), gzfle(), bzfile().
    • Példa: con <- file("filename.txt", "r"); readLines(5); close(con)
    • Fájl letöltése internetről: url("http://…")
  • Táblázatos adatok beolvasása: read.table(), pl. fruits <- read.table("table.txt"). Alapértelmezésben fejléc nélküli, vesszővel elválasztott fájlként olvassa be . Az eredmény adatkeret lesz, a típusokat megpróbálja kitalálni. Paraméterekkel sok minden beállítható. Hasonló függvény a read.csv(), ami a read.table() függvényt hívja meg olyan paraméterekkel, hogy az megfeleljen a csv fájltípusnak (pl. fejléccel).
  • Excel: library(xlsx), read.xlsx("fájlnév.xlsx"), read.xlsx2("fájlnév.xlsx"), write.xlsx("fájlnév.xls")
  • XML:
    • library(XML)
    • doc <- xmlTreeParse("fájlnév.xml") - XML beolvasása
    • node <- xmlRoot(doc) - a gyökér node lekérése
    • names(node) - egy node alatti node-ok nevei
    • node[[1]] - egy node alatti első elem lekérdezése
    • xmlSApply(node, xmlValue) - a fájl részeinek lekérdezése
    • xpathSApply(node, "xPathKifejezés", xmlValue) - XPath lekérdezés
  • HTML:
    • doc <- htmlTreeParse("fájlnév.html")
    • A többi függvény az XML-hez hasonló.
  • JSON
    • library(jsonlite)
    • jsonData <- fromJSON("uri") - beolvasás
    • toJson(jsonData) - kiírás
    • names(jsonData) - mező nevek
    • jsonData$name - egy adott mező elérése
  • Adattáblák (data tables): hasonló mint az adat keret (data frame), viszont sokkal több lehetőséget nyújt.
    • library(data.table)
    • dt <- data.table(…)
  • MySQL
    • library(RMySQL)
    • dbConn <- dbConnect(MySQL(), user="username", password="password" host="hostname", port="port", dbname="dbname")
    • dbListTables(dbConn)
    • dbListFields(dbConn, "tablename")
    • dbReadTable(dbConn, "tablename")
    • fetch(dbSendQuery(dbConn, "SELECT …"))
    • dbDisconnect(dbConn)
  • HDF5 (nagy adathalmazok tárolására)
    • library(rhdf5)
    • h5read(…)
    • h5write(…)
  • API
    • library(httr)
    • GET("URL")
  • Más statisztikai csomag: library(foreign), majd pl. read.spss().
  • Más adatbázisok: library(RPostgreSQL), library(RODBC) (PostgreQL, MySQL, Microsoft Access, SQLite), RMongo
  • Képek: library(jpeg), library(readbitmap), library(png)
  • GIS (térképek): library(rgdal), library(rgeos), library(raster)
  • Zene: library(tuneR), library(seewave)

Vezérlés

Az R-ben rendelkezésre áll az összes gyakori, más programozási nyelvben megszokott vezérlő szerkezet, így igazi programozási nyelvként is használhatjuk, nemcsak statisztikai céleszközként:

  • Feltételkezelés: if (…) {…} else if (…) {…} else {…}. Annyiba eltér a legtöbb programozási nyelvben megszokottól, hogy hogy lehet neki visszatérési értéke, mégpedig az utolsó kiértékelés eredménye. Így pl. használhatjuk ezt: x <- if (y > 3) {5} else {6}.
  • Véges ciklus: for(…) {…}, pl. for (i in 1:10) {print(i)}.
  • Elöltesztelős végtelen ciklus: while (…) {}, pont úgy működik, ahogy azt elképzeljük.
  • Végtelen ciklus: repeat {…} (ki tudja, miért gondolták ezt hasznosnak a nyelv megalkotói…).
  • Megszakítás: break.
  • Következő elem (megfelel a máshol megszokott continue-nak): next.

Függvények

A függvény a másik olyan lehetőség, ami szerethetővé teszi az R-t a programozók körében is. Mindenféle magyarázat előtt álljon itt egy példa, ami a legtöbb kérdést megválaszolja:

> add <- function(a, b) {a + b}
> add(2, 3)
[1] 5

Néhány fontos információ:

  • A függvény eredménye az utoljára meghatározott érték. Ha szeretnénk, kitehetjük a return(result) utasítást (mondjuk javítja az olvashatóságot), de el is hagyhatjuk.
  • A paraméterek típusait nem kell megadni, csak a neveit (sajnos…)
  • A paramétereknek lehet alapértelmezett értékük, melyet egyenlőség jellel adhatunk meg.
  • Híváskor paramétereket nevesítve is megadhatjuk egyenlőségjellel, pl. add(b = 3, a = 2). A látszat ellenére ennek komoly jelentősége van, és szerintem érdemes lenne máshol is bevezetni. Számos függvénynek tucatnyi paramétere van, többségük alapértelmezett értékkel, és így kiválogathatjuk azt a párat, melyet mi szeretnénk megadni. Ezen kívül az olvashatóságot is javítja, és megoldás lehet a magic number problémára.
  • Létezik a var-arg mechanizmus; a paramétert így kell megadni: . Ezt tipikusan továbbítjuk egy másik függvénynek, de listává is tudjuk alakítani (list(…)). Hasznos lehet pl. ha saját diagram készítőt implementálunk, ami a legvégén meghívja a plot() függvényt; annak tudjuk továbbítani az ő paramétereit.
  • Scoping: a tanfolyam egész hosszasan foglalkozik ezzel, és viszont szándékosan rövidre zárom a témát. Kb. úgy működik, ahogy elvárjuk, úgy éri el a globális változókat, függvényeket. Viszont egyrészt szerintem nem célszerű egy függvénynek belepiszkálni a globális adatokba, másrészt ha nem nyilvánvaló a scoping a megvalósításkor, akkor még kevésbé lesz nyilvánvaló a karbantartáskor, így egyszerűen kerüljük a témát.

Ciklusfüggvények

A ciklusfüggvények nevében szerepel az, hogy apply. Arról van szó, hogy egy adathalmaz elemire végrehajt egy műveletet, paraméterül átadva neki egyesével az adathalmaz elemeit. Valójában tehát kb. ekvivalens azzal, mintha végig iterálnánk az input elemein, és egyeséve végrehajtanánk a műveletet, viszont sokkal tömörebb.

Jellegzetes eleme az R programozási nyelvnek, így szinte elkerülhetetlen, hogy belefussunk, emiatt itt is megtalálható. Alkalmazni viszont csak óvatosan érdemes, mert drasztikusa rontja a kód olvashatóságát, különösen akkor, ha a kód olvasója R-ben kevésbé járatos.

  • lapply(): a függvény első paramétere egy lista, melynek elemeit egyesével átadja a második paraméternek első elemként, ami egy függvény. Utána tetszőleges számú paramétert megadhatunk még, ami a második paraméterként megadott függvény további paraméterei lesznek. A bemenet és a kimenet is mindig lista (tehát pl. ha a bemenet 1:5, akkor abból olyan 5 elemű lista lesz, melynek eleme egyelemű vektorok). Példa: lapply(list(1:5, 3:9), mean). Itt először meghívja a mean(1:5), majd a mean(3:9) átlagot számoló függvényt, az eredmény pedig olyan kételemű lista lesz, melynek első eleme a 3-at tartalmazó egyelemű vektor, míg a második eleme a 6-ot tartalmazó egyelemű vektor.
  • sapply(): hasonló az előzőhöz, viszont az eredményt próbálja egyszerűsíteni, pl. sokkal könnyebben kezelhető vektorrá alakítani. Pl. az sapply(list(1:5, 3:9), mean) eredménye a 3 és 6 elemekből álló kételemű vektor.
  • apply(): a nevéből levonható következtetéssel ellentétben ez egy egészen speciális eset: egy mátrix sorain vagy oszlopain hajtja végre a műveletet. Az első paramétere tehát egy mátrix, a második azt jelzi, hogy soronként (1) vagy oszloponként (2) hajtsa-e végre a műveletet (és igazán létrehozhattak volna neki valami konstanst, pl. byRows és byColumns), majd jön a függvény és a további paraméterek. Pl. az apply(matrix(1:6, 3, 2), 2, mean) hívásban a mátrix 3 sort és 2 oszlopot tartalmaz, az átlag (mean) számítást oszloponként hajtja végre (2), és mivel az első sozlop elemei az 1, 2 és 3, a másodiké pedig a 4, 5 és 6, az eredmény a 2 és 5 számokból álló kételemű vektor lesz.
  • mapply(): egy bizonyos függvényt (első paraméter) hajt végre a második és harmadik paraméter kombinációiból. Pl. a mapply(rep, 1:4, 4:1) függvény ekvivalens ezzel: list(rep(1, 4), rep(2, 3), rep(3, 2), rep(4, 1)). (A rep() függvény ismétlést jelent, pl. a rep(1, 4) eredménye 1, 1, 1, 1.)
  • tapply(): első paraméterként egy vektort vár, másodikként pedig faktort (vagy faktorként értelmezhető vektort), és a harmadik (és további) paraméterként megadott függvényt olyan bontásban hajtja végre, ahogyan azt a faktor kijelöli. Pl. a tapply(1:20, c(rep("a", 5), rep("b", 10), rep("c", 5)), mean) először három csoportra bontja az 1..20 közötti számokat, az első 5 lesz az 'a', a következő 10 a 'b', végül az utolsó 5 a 'c' kategória, és ezeken hajtja végre az átlagszámítást. Az eredmény ennek megfelelően a következő 3 elemű vektor lesz: 3.0, 10.5, 18.0, az elemek megfelelően elnevezve rendre a-bal, b-vel és c-vel. Ehhez kapcsolódó függvény a split(), amely a az első paraméterként átadott vektort bontja részekre a második paraméterként átadott faktor alapján, pl. split(1:20, c(rep("a", 5), rep("b", 10), rep("c", 5))).

Dátumkezelés

Rendes időkezelést még nem láttam. Mindenhol van valami, ami kellően komplikált és kellően ritkán használt ahhoz, hogy ne lehessen fejben tartani a szintaxist. Majd rendre megjelenik az "egyszerűsítés", ami a felülről kompatibilitás kényszere miatt gyakorlatilag még jobban összekuszálja a szálakat. Nincs ez másképp az R-ben sem. Lássuk a részleteket:

  • A rendszerórát így tudjuk lekérdezni: Sys.time()
  • A POSIXlt típus tartalmazza a szokásos felbontást. Pl. azt, hogy az év hányadik napja a mai, így tudjuk lekérdezni: as.POSIXlt(Sys.time())$yday
  • A POSIXct a háttrében gyakorlatilag a UNIX rendszeróra másodperce, melynek lekérdezése - miért is lenne egyszerű az élet - így nét ki: unclass(as.POSIXct(Sys.time()))
  • Ha pedig egy saját formátumot szeretnénk beolvasni, azt a következő, nehezen megjegyezhető nevű és logikátlan paraméterlistájú függvénnyel tudjuk megtenni: strptime("2019-03-29 07:25:12", "%Y-%m-%d %H:%M:%S")
  • Alap műveleteket végre tudunk hajtani a dátumokon, pl. egymásból ki tudjuk őket vonni.

Szimuláció

Sokféle eloszlású számokkal lehet 4 féle műveletet végrehajtani. A függvények mindegyike a műveletnek megfelelő betűvel kezdődik:

  • d - sűrűség (density), pl. normális eloszlás esetén ez a haranggörbe
  • p - kumulatív eloszlás (cumulative distribution); ez a sűrűség kumulálásából adódik, 0-ból indul, 1-be ér
  • q - qvantilis (quantile); ez a p inverze
  • r - véletlen szám generálás (random number generation)

Néhány fontosabb eloszlás:

  • norm - normális
  • pois - Poisson
  • exp - exponenciális
  • unif - egyenletes

Pl. a rnorm(10) 10 darab standard normális eloszlású véletlen számot generál.

Hibakeresés

Ha egy hiba okát szeretnénk megtalálni, olyan szintű hibakeresési lehetőségekre ne számítsunk, mint mondjuk a Java esetén rendelkezésünkre áll, de azért az R-ben is van pár lehetőség.

Stack trace

Egy hiba lokalizációjában sokat segít az ún. stack trace, azaz a hívási lánc. Parancssoros végrehajtás után adjuk ki a traceback() függvényt, és akkor megjelenít egy hevenyészett hívási láncot, nagy vonalakban megjelölve azt, hogy hol jött elő a hiba.

Debug

A program sorokat egyesével végrehajtani az egyik leghasznosabb hibakeresési módszer. Az R-ben kissé nehézkes, de működik. Ha a függvény neve, amit debuggolni szeretnénk, func, akkor adjuk ki ezt a parancsot: debug(func) (így, paraméterek nélkül), majd hívjuk meg a func() függvényt, megfelelően felparaméterezve. Ekkor nem fut le, hanem egyesével tudunk lépkedni a n beírásával. Ha már nem szeretnénk debug módban indítani, akkor hívjuk meg az undebug(func) függvényt.

Profiling

Nehezebb a dolgunk, ha a programunk funkcionálisan jól működik ugyan, viszont lassú. Ebben segítséget nyújthat az Rprof() függvény, ami mintavételezéssel készít statisztikákat. Alapértelmezésben nem csinál semmi hasznosít; ha pl. memória problémáink vannak, akkor érdemes így kiadni: Rprof(memory.profiling = TRUE). Az alapértelmezett mintavételezési gyakoriság 2 századmásodperc, így a fenti parancs kiadása után egy legalább ennyi ideig futó programot indítsunk. Ha befejeződött, akkor adjuk ki a summaryRprof() parancsot.

Az adatok beszerzése és tisztítása

Kurzus: https://www.coursera.org/learn/data-cleaning/

Nyers adat -> feldolgozás -> tiszta adat. A következő 4 dologra van szükség:

  • nyers adat (annak a forrása, a beszerzés időpontja),
  • tiszta adat (minden mért változó egy oszlop legyen; mindegyik mérés egy sor legyen; egy táblázat egyfajta adatot tartalmazzon; több tábla esetén legyen kapcsoló oszlop),
  • a tiszta adat leírása (mértékegységekkel),
  • annak leírása, hogy hogyan kaptuk meg a nyers adatból a tiszta adatot (ha lehet, érdemes scriptet írni, és azt mellékelni).

(A fent ismertetett adatok beolvasása és átalakítása rész döntőrészt ebből a tanfolyamból származik.)

Felderítő adatelemzés

Kurzus: https://www.coursera.org/learn/exploratory-data-analysis/

Megismételhető kutatás

Kurzus: https://www.coursera.org/learn/reproducible-research/

Statisztikai következtetés

Kurzus: https://www.coursera.org/learn/statistical-inference/

Regressziós modellek

Kurzus: https://www.coursera.org/learn/regression-models/

Alkalmazott gépi tanulás

Kurzus: https://www.coursera.org/learn/practical-machine-learning/

Adattermékek fejlesztése

Kurzus: https://www.coursera.org/learn/data-products/

Adattudomány záró projekt

Kurzus: https://www.coursera.org/learn/data-science-project

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License