Rで高速に大量データを読み込んでデータフレームに格納する方法 (2)
前回,read.table()とscan()を比較したんですが,もう少しきちんと調べてみると,実はread.tableパッケージというものがあるということを知りました.さらにstackoverflowにドンピシャのスレッドを見つけたので,これを実際に確かめてみました.
freadの検証
data.tableパッケージが高速なテーブルデータの読み込みをおこなうためのパッケージで,中でもfreadが最もパフォーマンスが高いようです.
## user system elapsed Method ## 24.71 0.15 25.42 read.csv (first time) ## 17.85 0.07 17.98 read.csv (second time) ## 10.20 0.03 10.32 Optimized read.table ## 3.12 0.01 3.22 fread ## 12.49 0.09 12.69 sqldf ## 10.21 0.47 10.73 sqldf on SO ## 10.85 0.10 10.99 ffdf
via import - Quickly reading very large tables as dataframes in R - Stack Overflow
ということで,下記のようなコードで検証してみました.system.time()で処理に要した時間が測れます.
install.packages("data.table") library(data.table) require(data.table) system.time(data <- fread("~/Documents/tmp/sample_20000000.dat")) system.time(class(data) <- "data.frame") system.time(names(data) <- c("uid", "sex", "age"))
結果
159.134 + 0.352 + 9.237 = 168.723秒ということで,先ほどと比べて相当に読み込み時間が短縮されました.まぁ,下記の結果をみる限り,もっとも効果があったのは,data.frame()を使わなかったためなのですが...
> system.time(data <- fread("~/Documents/tmp/sample_20000000.dat")) user system elapsed 153.813 1.776 159.134 > system.time(class(data) <- "data.frame") user system elapsed 0.196 0.156 0.352 > system.time(names(data) <- c("uid", "sex", "age")) user system elapsed 8.979 0.258 9.237
以上,freadで読み込んで,classとnamesだけ変えてデータフレームにするのが一番効率的みたいですね.
ちなみに
前回のscan()を同じように処理してみたら,freadの1.5倍以上時間がかかっていたみたいですね.やはりscanよりもさらにfreadのほうが断然良いみたいです.そしてscanではあくまでリストでの読み込みでしかないので,classとnameの変換をしても,正しく処理されてくれませんでした.なので,data.frame()にかかる時間を考えると,なおさらfread一択っぽいですね.
> system.time(data <- scan("/Users/smrmkt/Documents/tmp/sample_20000000.dat", + list(user_id="", sex="", age=0))) Read 20000000 records user system elapsed 287.967 3.085 291.143