Arról, miként nézzen ki egy táblázat, már írtam korábban, hogy miként tároljuk azokat, még nem esett szó. Erre több módszer is létezik, ezekből szemezgetnék párat a teljesség igénye nélkül. A következő teszteket a GTEx RNA-seq táblázatával próbáltam ki, ami 1.7GB méretű. Ezt bárki letöltheti és további próbákat tehet vele. Az oszlopok az EnsEMBL gén azonosítók, az oszlopok pedig a megszekvenált minták.
Szöveges állományok
Természetesen a legegyszerűbb megoldás, ha csak úgy hagyjuk őket, ahogy vannak. A legnépszerűbb megoldások a tabulátorral vagy pontosvesszővel elválasztott szövegek (a GTEx az előbbi). Ezeket R-ben például nagyon egyszerű betölteni.
d1 <- read.table("count.tsv", check.names = F, sep = "\t")
Ha viszont megnézzük, milyen sebességgel kerül a memóriába ez a fájl, már nem olyan vidám a helyzet. A tesztelésre használt gépen ez 217.721 másodpercet vett igénybe. A readr csomag sokat lendíthet az olvasási sebességen.
d2 <- read_table2("count.tsv")
Ez kevesebb, mint fele idő alatt dolgozza fel a táblázatot (90.63 mp). De mi a helyzet, ha a rendelkezésre álló memória nem teszi lehetővé, hogy mindent beolvassunk? Szerencsére erre is van megoldás. A bigmemory csomag segítségével nem csak beolvashatjuk a táblázatunkat, de olyan elemzéseket is végezhetünk, amelyek korábban lehetetlenek lettek volna a kevés memória miatt.
d3 <- read.big.matrix("count.tsv", header = T)
Ez igazi sebesség, 36.569 másodperc! De sajnos van egy nagy hátránya a tisztán szöveges adatnak. Először is a metainformációk kezelése nehézkes. Képzeljük csak el, ha csak az agyból származó mintákkal akarunk foglalkozni. Valahogy ki kéne őket szűrni, de ahhoz egy másik táblázatot kellene felhasználnunk.
Természetesen nem megoldhatatlan a probléma, de miért mi párosítsuk az adatokat, ha erre már létezik kész megoldás?
SQL adatbázisok
Ez az adattárolás teljesen más formája. Egyrészt a táblák közötti kereszt referenciák kezelése jóval egyszerűbb lesz, másrészt maguk a táblázatok formája át fog alakulni. Az SQL nem teszi lehetővé, hogy mátrixunkat sor-oszlop formában tároljuk. Át kell alakítani azt egy három oszlopos formába, ahol az első oszlop a sor azonosító, a második az oszlop azonosító, a harmadik pedig a cella értéke, jelen esetben a nyers expressziós érték:
gene | sample | count |
ENSG00000223972.4 | GTEX-1117F-0226-SM-5GZZ7 | 3 |
ENSG00000223972.4 | GTEX-111CU-1826-SM-5GZYN | 4 |
Elsőre talán bonyolultnak tűnik ez a tárolási módszer, de van egy előnye: többé nem kell két dimenzióba gondolkodnunk. A szöveges állományok esetén egy ha egy újabb dimenzióval szeretnénk bővíteni a táblázatot, akkor az rengeteg többlet munkával jár. SQL esetén mindez egy új oszlop felvételét jelenti.
Most már készíthetünk egy új táblát, amiben megfeleltetjük az EnsEMBL azonosítókat gén szimbólumoknak, adhatunk hozzájuk kromoszóma pozíciókat, bármit, amit szeretnénk. A semmit mondó minta azonosítókhoz is rendelhetünk további információkat, mint amilyen a páciens neme, a szövet típusa vagy a mintavétel ideje. Miként használhatjuk ezt R-ből?
Ha például MySQL-ben (vagy MariaDB-ben) csináljuk mindezt, akkor használhatjuk az RMySQL csomagot.
library(RMySQL)
con <- dbConnect(MySQL(), user="user", password="abc123", dbname="gtex", host="localhost")
rs <- dbSendQuery(con, "select * from count")
raw <- fetch(rs, n = -1)
count <- xtabs(count ~ gene + sample, data = raw)
count <- as.data.frame.matrix(count)
Sajnos ez a nagyfokú szabadság nincs jó hatással a sebességre. Bármilyen optimalizáció nélkül a fenti kódot kb. 10 perc után leállítottam, mert 32GB RAM mellett is swappelt.
NoSQL adatbázisok
Számomra igazi meglepetés, hogy nincs olyan NoSQL adatbázis, ami képes lenne GTeX mennyiségű adat tárolására. Természetesen, aki nagyon akarja, bele tudja erőltetni az adatokat bármibe, de a BigTable típusú adatbázisok alapesetben képtelenek kezelni több ezer oszlopot. A HBase 3-4 oszloppal boldogul hatékonyan. A Google-féle BigTable büszkén hirdeti, hogy 100 oszlop családdal is megbírkózik, míg a HyperTable max. 255-öt kezel. Ez meglepetés volt nekem.
Összegzés
Mikor elkezdtem ennek a posztnak az írását, abban reménykedtem, hogy a végén találok egy olyan megoldást, ami hatékonyan kezeli a nagy táblázatokat. A sok telepítés és próbálgatás után viszont úgy látom, egy ideig nem szabadulunk meg a jó öreg szöveges állományoktól. Akinek a fenti megoldásokon kívül jobb ötlete van, kommentben nyugodtan írja meg.