R-ohjelmointi.org

Tilastotieteellistä ohjelmointia R-kielellä

Tekstitiedostojen lukeminen R:ään nopeasti: read.table, read_table ja fread

Johdanto
Lienee jokseenkin tunnettu tosiseikka, että R:n tavanomainen funktio read.table() on melko hidas. Tiedostoja on mahdollista lukea paljon nopeamminkin eräiden laajennuspakettien funktioilla. Tällainen on esimerkiksi paketin data.table funktio fread(). Nyt markkinoille on tullut Hadley Wickhamin uusi paketti readr, jonka funktio read_table() on tarkoitettu nopeuttamaan datan lukemista R:ään.

Testejä R:ssä
Kokeillaanpa. Testinä on aineisto, jossa on n. 640 000 riviä ja 102 saraketta, joiden datatyyppi vaihtelee. Tulos näyttää seuraavalta (kolmen replikaatin keskiarvo on oleellisesti sama):

system.time(d<-read.table("mat.csv", header=T, sep=";"))
   user  system elapsed 
  59.45    2.31   62.82 
 
# Optimoitu read.table
system.time(d<-read.table("mat.csv", header=T, sep=";", nrows=3))
system.time(d<-read.table("mat.csv", header=T, sep=";", colClasses=rep("character", ncol(d)), comment.char="", stringsAsFactors=FALSE))
   user  system elapsed 
  54.78    1.61   56.68 
 
library(readr)
system.time(d<-read_delim("mat.csv", col_names=T, delim=";"))
   user  system elapsed 
  32.20    0.39   34.01 
 
library(data.table)
system.time(d<-fread("mat.csv", header=T, sep=";"))
   user  system elapsed 
  12.47    0.19   12.91

Eli read_table() -funktio tiputtaa datan latausajan read.table() -funktioon verrattuna noin puoleen, mutta fread() on edelleen verrattomasti nopein.

Python ja muut data-analyysiohjelmistot
Entäs muut ohjelmistot? Esimerkiksi Python on varsin vertailukelpoinen R:n fread() -funktion kanssa:

if 1:
   from datetime import datetime
   print str(datetime.now())
   import pandas as pd
   dat = pd.read_csv('mat.csv',sep=';',header=0)
   print str(datetime.now())

2015-04-12 14:34:38.884000
2015-04-12 14:34:54.224000

Pythonilla (versio 2.7.8) saman tiedoston lukemiseen meni yhteensä hieman yli 15 sekuntia.

Vertailun vuoksi kellotin vielä PSPP:n, joka on SPSS-ohjelmiston OSS-klooni. PSPP:llä datatiedoston avaamiseen meni n. 3 minuuttia ja 30 sekuntia (210 sekuntia). Microsoft Officen Excel-ohjelmisto puolestaan suoriutui koitoksesta 91 sekunnissa.

Hankalien tiedostojen käsittely
Eräänä huomioitavana seikkana on, että jos luettava tiedosto on siisti, on hyvin mahdollista käyttää datan lukemiseen fread() -funktiota. Sen sijaan jos tiedosto ei ole siisti, vaan siellä on esimerkiksi kommenttimerkkejä,
päättämättömiä lainausmerkkejä ja ”solujen” sisäisiä rivinvaihtoja (kaikki ovat hyvin tyypillisiä ongelmia), ei fread() suoriudu kunnialla. Tällöin erikoisuuksien käsittelyn paremmin mahdollistava read.table() nouseekin omaan arvoonsa, koska sillä voi helposti huomioida tällaisia erikoistilanteita.

Tällaisissa vaikeammissa erikoistilanteissa voi myös olla tarpeen lukea tiedosto esim. readLines() -funktiolla tai readChar() -funktiolla, jolloin on mahdollista esimerkiksi muuttaa rivinvaihtomerkintöjä ym. Esimerkkitiedoston readLines() luki alle 26 sekunnissa, ja readChar() 1.1 sekunnissa. Kumpikaan ei tosin huomioi sitä, että data haluttiin taulukkomuotoon, mutta näitä funktioita ei ole siihen tarkoitettukaan.

Nopeampikin readLines on tosin helppo luoda. Esimerkiksi:

# 1.05 s.
system.time(rc<-readChar("mat.csv", nchars=file.info("mat.csv")$size))
 
# 6.33 s.
system.time(ss<-strsplit( rc,"\n",fixed=T,useBytes=T)[[1]])

Mutta tuloksena syntyvän vektorin muuntaminen (nopeasti) taulukkomuotoon ei ole ihan helppoa.

Yhteenveto
R ei ole mitenkään mahdottoman hidas lukemaan tiedostoja, jos vain käytetään soveltuvia funktioita (esim. fread()). Puhtaan datan saa tarvittaessa luettua hyvinkin nopeasti R:ään (fread()). Samaten erilaisten ongelmien korjausoperaatioiden vaatiman datan saa luettu hyvin nopeasti (esim. readChar()), mutta ennen lopullisen datan lukemista välivaiheena on miltei pakollinen levylle kirjoitus, koska R:ssä datamuodon konversio (ks. yllä) on melko hidasta, jos data on suurta.

Käytännössä R on nopeudeltaan täysin kilpailukykyinen esimerkiksi Pythonin kanssa, ja paljon nopeampi kuin monet tavanomaiset data-analyysissä käytetyt ohjelmistot. Tämä näyttää SPSS:n lisäksi ylestyvän esim. Stataan.


Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *