1. ホーム
  2. r

[解決済み] 非常に大きなテーブルをデータフレームとして高速に読み込む

2022-03-18 10:46:14

質問

非常に大きなテーブル(3000万行)があり、Rでデータフレームとして読み込みたいのですが、どうすればよいですか? read.table() は便利な機能が多いのですが、実装にロジックが多く、遅くなるような気がします。 私の場合、カラムの型が先に分かっていること、テーブルにカラムヘッダや行名が含まれていないこと、気になるような病的な文字がないことを前提に考えています。

を使用してテーブルをリストとして読み込むことは知っています。 scan() はかなり高速になります、例.

datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))

しかし、これをデータフレームに変換しようとすると、上記のパフォーマンスが6分の1に低下するように見えるものがあります。

df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))

もっと良い方法はないのでしょうか? あるいは、まったく別のアプローチで問題を解決できる可能性はありませんか?

解決方法は?

数年後のアップデート

この回答は古く、Rは前進しました。 手直し read.table を使っても、ほとんど効果はありません。 あなたの選択肢は

  1. 使用方法 vroom tidyverseパッケージから vroom csv/tab区切りファイルからRのtibbleに直接データをインポートするためのものです。参照 Hectorの回答 .

  2. 使用方法 fread data.table は、csv/tab-delimited ファイルから直接Rにデータをインポートするためのものです。 mnelの回答 .

  3. 使用方法 read_table readr (2015年4月よりCRANにて)。 これは、以下のように動作します。 fread 上記の また リードミー の2つの関数の違いについて、リンク先で説明しています( readr と比べて1.5~2倍遅いと言っています。 data.table::fread ).

  4. read.csv.raw から iotools は、CSVファイルを素早く読み込むための第3の選択肢を提供します。

  5. できるだけ多くのデータをフラットファイルではなく、データベースに保存しようとすること。 (永久保存媒体として優れているだけでなく、データはバイナリ形式でRとの間で受け渡しされるため、より高速になります)。 read.csv.sql の中に sqldf パッケージで説明されているように JD Longの回答 は、データを一時的な SQLite データベースにインポートし、それを R に読み込みます。 RODBC パッケージの逆依存セクションと DBI パッケージ のページをご覧ください。 MonetDB.R は、データフレームのように見せかけて、実はその下はMonetDBであるというデータ型を与え、パフォーマンスを向上させます。 データをインポートするには monetdb.read.csv 関数を使用します。 dplyr は、いくつかのタイプのデータベースに保存されたデータを直接操作することができます。

  6. また、バイナリ形式でデータを保存すると、パフォーマンスの向上に役立つことがあります。 使用方法 saveRDS / readRDS (後述)を使用すると h5 または rhdf5 HDF5 形式のパッケージ、または write_fst / read_fst から fst パッケージを使用します。


回答原文

read.tableを使うにせよscanを使うにせよ、試してみるべき簡単なことが2つあります。

  1. セット nrows = データ内のレコード数 ( nmaxscan ).

  2. を確認してください。 comment.char="" をクリックすると、コメントの解釈をオフにすることができます。

  3. 各カラムのクラスを明示的に定義するには colClassesread.table .

  4. 設定方法 multi.line=FALSE は、スキャン時のパフォーマンスも向上させることができます。

もし、どれもうまくいかない場合は、次のいずれかを使ってください。 プロファイリング・パッケージ どの行が処理を遅くしているのかを判断するためです。 おそらく read.table その結果をもとに

もう一つの方法は、Rに読み込む前にデータをフィルタリングすることです。

あるいは、定期的に読み込まなければならないことが問題なのであれば、これらの方法を使って一度だけデータを読み込み、データフレームをバイナリブロブとして保存し save saveRDS を使えば、次回からはより速く取得することができます。 load readRDS .