StatsBeginner: 初学者の統計学習ノート

統計学およびR、Pythonでのプログラミングの勉強の過程をメモっていくノート。たまにMacの話題。

Rメモ: サイズの大きいcsvファイルを読み込むときはdata.tableを使う

 私はcsvをRに読み込むときはread.csv()でやってたわけですが、↓のような解説を読むと、どうやら大きなデータを読み込むときにread.csv()とかやってる奴は論外らしい。


 data.tableパッケージで大規模データをサクッと処理する
 Rで高速に大量データを読み込んでデータフレームに格納する方法 (1) - About connecting the dots.
 Rで高速に大量データを読み込んでデータフレームに格納する方法 (2) - About connecting the dots.


 data.tableというパッケージを使うのが良いようです。data.tableパッケージの基本的な使い方は、奥村先生のホームページにも書いてありました。

data.frame の読み込みは read.csv() などのいくつかの関数で行いましたが,data.table の読み込みは fread() だけです。


data = fread("ファイル名またはURL")
CSVかTSVか,ヘッダがあるかないかは,たいてい自動判断してくれます。もしうまくいかなかったら,オプションで指定します。


data = fread("ファイル名またはURL", sep=",", header=TRUE, na.strings=c("NA",""))


data.table


 というわけで自分でも試してみました。
 system.time()という関数を使うと、()の中に書いた処理の所要時間が計測できるというのも、今日知りました。


 まず、read.csv()で、だいたい450MBぐらいあるcsvファイル(150万行ぐらい)を読み込んでみます。

> system.time(data1 <- read.csv("2223.csv", header=FALSE))
   user  system elapsed 
388.361  32.726 519.112 
> 
> nrow(data1)  #行数を確認
[1] 1501298


 3つ並んでいる数字*1のうち、3つめのelapsedが最終的な経過時間ですね。519秒なので8分以上かかっています。
 かかりすぎだろwww
 userというのはCPUが実際に処理している時間で、systemというのは表示とかにかかっている時間らしいですが、意味はよく分かりません。


 で、data.tableというパッケージを使ってみます。

> library(data.table)
data.table 1.9.2  For help type: help("data.table")
> system.time(data2 <-fread("2223.csv", header=FALSE)) 
Read 1501298 rows and 58 (of 58) columns from 0.451 GB file in 00:00:06
   user  system elapsed 
  5.313   0.704   7.964 
of 58) columns from 0.451 GB file in 00:00:06


 ファッッ!?


 7.964秒で読み込みが終わりました。
 read.csv()だと8分かかったのが、fread()では8秒で終了……。


 なお、今回のデータの場合に限るのかもしれませんが、読み込んだ後のデータフレームについて列ごとにclassを確認したところ、read.csv()だと自動的に、概ね良い感じでnumericやfactorが指定されていましたが、fread()のほうでは全部numericになっていました。


 というかそもそも、data.tableで読み込んだデータフレーム自体も、従来のdata.frameとは別のオリジナルな感じのclassになっているようです。ふつうのデータフレームの操作みたいなことをしたときに、予想外の結果が返ってくるので、きちんと仕様をしらべてから使わなければならないようだ。
 ただ、as.data.frame()で普通にデータフレームに変換するのは一瞬でできたので、data.tableの機能を使わず単に高速に読み込みたいだけだったのであれば、そうすればいいかもしれない。

[1] "data.table" "data.frame"
> class(data1)
[1] "data.frame"
> class(data2)
[1] "data.table" "data.frame"


  fread()は、全体の行数の何%を読み込んだかもコンソールに表示してくれてちょっとかっこいいです。



 ※今やってみてわかりましたが、はてなブログは基本機能ではvineの埋め込みには対応してないんですね。vine側で埋め込み用のコードを生成すれば貼れますが。

*1:Web上の解説では数字が5つ並んでいるものが多いが、最後の2つは副プロセッサによる処理時間というやつで、ほとんどの場合はゼロで、表示されないらしい。