私は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",""))
というわけで自分でも試してみました。
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つは副プロセッサによる処理時間というやつで、ほとんどの場合はゼロで、表示されないらしい。