素早く読みは非常に大きなテーブルとしてdataframes
質問
私は非常に大きなテーブル(30万行)いと思うようにな負荷としてdataframesでR. read.table()
多くの便利な機能がそうであるロジック、実施が遅いものです。私の場合、私とピックアップしました。種類のカラム、フォントのテーブルが含まれていない列のヘッダーまたは列名な病態の文字としています安心です。
知っている読みのテーブルのリストとして使用 scan()
れぞれの知見について学ぶととも速く、例えば:
datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))
それからの試みに変換することで、こdataframeが減の性能を上記の効果を明確にする必要がある6:
df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))
あれ?またはあるにも関わら完全に異なるアプローチに問題なのでしょうか。
解決
アムステルダムの数年後
この答えは古いですが、R移動します。調整 read.table
ラビットの高速化が少ない貴重なる。選択肢は、次の通りです:
を使用
fread
にdata.table
輸入からデータをcsv/タブ区切りのテキストファイルを直接R.見 mnelの回答.を使用
read_table
にreadr
(CRAN月日から2015年))が見込まれています。この作品のようにfread
ます。の readme リンクにつの違いは二つの機能readr
現在の主張"1.5-2倍速が遅"よりdata.table::fread
).read.csv.raw
からiotools
提供のオプションのための速読むCSVファイルです。う店舗としてのデータとしての中でも特に効能が高いと言われるデータベースではなく平坦なファイルです。(どのより恒久的な保存中のデータが渡されたとRバイナリフォーマットである。)
read.csv.sql
のsqldf
パッケージに記載のとおり JD長の回答, 輸入データの一時的なSQLiteデータベースを読み込みでR.参照:のRODBC
パッケージには、のり部DBI
パッケージ ページです。MonetDB.R
きのデータタイプのぬふりをするデータフレームではMonetDBの下に増加。データをインポートとそのmonetdb.read.csv
機能です。dplyr
き成長を続けるリテール企業にて、データが保存されて数種類のデータベースです。データを格納するバイナリ形式でも可能の改善に役立ちます。使用
saveRDS
/readRDS
(以下参照)、h5
またはrhdf5
パッケージHDF5形式、またはwrite_fst
/read_fst
からfst
パッケージです。
の答え
があり簡単なものしか使用します。テーブルやスキャン!
セット
nrows
=レコード数をデータ (nmax
にscan
).う
comment.char=""
をoffに解釈す。明示的に定義するクラスの各カラムを使用
colClasses
にread.table
.設定
multi.line=FALSE
もパフォーマンスの向上。
ない場合のこれらのこと、そしてするものではなく、一切の プロファイリングパッケージ るかを判定ライン速いものです。かいカット版 read.table
に基づきます。
その他のインタビューを受けたことがあフィルタリングデータの前に読んでR.
または、お問い合わせいに読んで、定期的にその使用方法を読みデータを一度押すと、データフレームとしてバイナリのblobと save
saveRDS
, その次に時間を取得することができますのでよりも速く load
readRDS
.
他のヒント
ここfread
1.8.7からdata.table
を利用する例である
の例は、私のWindows XPのコア2デュオE8400のタイミングで、fread
するヘルプページから来ています。
library(data.table)
# Demo speedup
n=1e6
DT = data.table( a=sample(1:1000,n,replace=TRUE),
b=sample(1:1000,n,replace=TRUE),
c=rnorm(n),
d=sample(c("foo","bar","baz","qux","quux"),n,replace=TRUE),
e=rnorm(n),
f=sample(1:1000,n,replace=TRUE) )
DT[2,b:=NA_integer_]
DT[4,c:=NA_real_]
DT[3,d:=NA_character_]
DT[5,d:=""]
DT[2,e:=+Inf]
DT[3,e:=-Inf]
標準read.tableを
write.table(DT,"test.csv",sep=",",row.names=FALSE,quote=FALSE)
cat("File size (MB):",round(file.info("test.csv")$size/1024^2),"\n")
## File size (MB): 51
system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))
## user system elapsed
## 24.71 0.15 25.42
# second run will be faster
system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))
## user system elapsed
## 17.85 0.07 17.98
最適化read.tableを
system.time(DF2 <- read.table("test.csv",header=TRUE,sep=",",quote="",
stringsAsFactors=FALSE,comment.char="",nrows=n,
colClasses=c("integer","integer","numeric",
"character","numeric","integer")))
## user system elapsed
## 10.20 0.03 10.32
にfread
require(data.table)
system.time(DT <- fread("test.csv"))
## user system elapsed
## 3.12 0.01 3.22
sqldf
require(sqldf)
system.time(SQLDF <- read.csv.sql("test.csv",dbname=NULL))
## user system elapsed
## 12.49 0.09 12.69
# sqldf as on SO
f <- file("test.csv")
system.time(SQLf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))
## user system elapsed
## 10.21 0.47 10.73
FF / FFDF
require(ff)
system.time(FFDF <- read.csv.ffdf(file="test.csv",nrows=n))
## user system elapsed
## 10.85 0.10 10.99
要約:
## 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
私が最初にこの質問を参照し、数日後に同様の質問をしていませんでした。私がダウンして私の前の質問を取るつもりですが、私は私がこれを行うためにsqldf()
を使用方法を説明するためにここに答えを追加しようと思いました。
へと議論するの少しがあったですRのデータフレームにテキストデータの2GB以上をインポートするための最良の方法。昨日、私は、ステージング領域としてSQLiteのデータをインポートするsqldf()
を使用する方法についてはブログ記事を書きましたその後、これは私のために本当によく働くRにSQLiteのからそれを吸います。私は<5分で2ギガバイトのデータの(3列、40ミリメートル行)を引くことができました。これとは対照的に、read.csv
コマンドはすべての夜を実行し、完了したことはありません。
ここに私のテストコードです。
テストデータを設定します:
bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)
私は、次のインポートルーチンを実行する前に、Rを再起動します:
library(sqldf)
f <- file("bigdf.csv")
system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))
私は次の行がすべての夜実行してみましょうが、それは決して完了ます:
system.time(big.df <- read.csv('bigdf.csv'))
不思議なことに、誰もが、これは重要なものであるにも関わらず年間、質問の下の部分に答えていない - data.frame
sは、単純にある右の属性を示していますので、あなたが大規模なデータを持っている場合は、as.data.frame
または類似を使用したくありませんリストのため。それは単にその場でデータフレームの中にリストを「オン」するためにはるかに高速です。
attr(df, "row.names") <- .set_row_names(length(df[[1]]))
class(df) <- "data.frame"
このは(他のすべてのメソッドとは異なり)、それは即時ですので、データのないコピーを行うものではありません。それはあなたがすでにそれに応じてリストにnames()
を設定していることを前提としています。
[Rに大規模なデータをロードするよう - 個人、私はバイナリファイルに列でそれらをダンプしreadBin()
を使用 - はるか(mmapping以外)最速の方法であり、唯一のディスク速度によって制限されます。 ASCIIファイルを解析してバイナリデータと比較して(さえCで)本質的に低速である。
このた たに R助, ので、その価値を検討している
一つ提案があった利用 readChar()
その文字列操作の結果 strsplit()
や substr()
.きのロジックに関わるreadCharは以下を読み込みます。表に示す。
わからない場合はメモリーの問題や、ここで入手できるかもしれませんが、も たいの HadoopStreaming パッケージ.この 使用Hadoop, であるMapReduceの枠組みの設計のための大きなデータを扱う。このために使うのhsTableReaderます。これは一つの例であることがわかっていても、学習曲線を学ぶHadoop):
str <- "key1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey2\t9.9\nkey2\"
cat(str)
cols = list(key='',val=0)
con <- textConnection(str, open = "r")
hsTableReader(con,cols,chunkSize=6,FUN=print,ignoreKey=TRUE)
close(con)
の基本的な考え方は、データに導入することによって、チャンク.きっとするものではなく、一切の並列の枠組み(雪にデータをインポートドラッグで並行単位でファイルが最も蓋然性が高い大規模データセットがないので助かったでメモリ制約、地図-削減がより優れたアプローチだ。
言及する価値がマイナーな追加ポイント。あなたは非常に大規模なファイルを持っている場合は、その場で(bedGraph
が作業ディレクトリにファイルの名前です)行数(ヘッダーなしの場合)を使用してを計算することができます:
>numRow=as.integer(system(paste("wc -l", bedGraph, "| sed 's/[^0-9.]*\\([0-9.]*\\).*/\\1/'"), intern=T))
あなたは、どちらのread.csv
で、read.table
...
>system.time((BG=read.table(bedGraph, nrows=numRow, col.names=c('chr', 'start', 'end', 'score'),colClasses=c('character', rep('integer',3)))))
user system elapsed
25.877 0.887 26.752
>object.size(BG)
203949432 bytes
代替が利用 vroom
パッケージです。今CRAN.vroom
な負荷の全体ファイルなので、指数の各レコードは、読み込み後するものとします。
のみを支払います。
見 紹介ヴ, にしたいと考える人は多いだろうヴ の ヴのベンチマーク.
の基本的な概要につきましては、初期の巨大なファイルは、素早く、以後の変更からのデータが少し遅くなります。なによりご利用ができる最高のオプションです。
参照簡易例から ヴのベンチマーク 以下のキー部品の超高速読みが少sower事業のように集計等。
package read print sample filter aggregate total
read.delim 1m 21.5s 1ms 315ms 764ms 1m 22.6s
readr 33.1s 90ms 2ms 202ms 825ms 34.2s
data.table 15.7s 13ms 1ms 129ms 394ms 16.3s
vroom (altrep) dplyr 1.7s 89ms 1.7s 1.3s 1.9s 6.7s
しばしば私はデータベース(例えば、Postgresの)内側に大きなデータベースを維持するだけで良い習慣だと思います。私はあまりにもはるかに大きい(nrow * NcoI部位)よりもかなり小さいncell = 10Mを、ものは使用しないでください。私は、多くの場合、私は複数のデータベースからの照会のみながらRはメモリ集約グラフを作成し、保持したい見つけます。 32ギガバイトのノートパソコンの将来的には、メモリの問題これらのタイプのいくつかは消えます。しかし、データを保持するデータベースを使用した後、得られたクエリ結果及びグラフのRのメモリを使用することの魅力は依然として有用であり得ます。いくつかの利点があります:
(1)のデータは、データベースにロードされたままになります。あなたは、単にあなたが背中にあなたのラップトップの電源を入れたとき、あなたがしたいデータベースにpgAdminでに再接続します。
(2)Rは、SQLよりも多くの気の利いた統計やグラフの操作を行うことができます本当です。しかし、私はSQLがRよりも大量のデータを照会するために設計された優れていると思います。
# Looking at Voter/Registrant Age by Decade
library(RPostgreSQL);library(lattice)
con <- dbConnect(PostgreSQL(), user= "postgres", password="password",
port="2345", host="localhost", dbname="WC2014_08_01_2014")
Decade_BD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from Birthdate) from voterdb where extract(DECADE from Birthdate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")
Decade_RD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from RegistrationDate) from voterdb where extract(DECADE from RegistrationDate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")
with(Decade_BD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Birthdays later than 1980 by Precinct",side=1,line=0)
with(Decade_RD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Registration Dates later than 1980 by Precinct",side=1,line=0)
の代わりに、従来はread.tableの私は、関数freadが速く機能であると感じています。 要因としてcolclassesと文字列を指定して、選択のみ必要な列などの追加の属性を指定すると、ファイルをインポートするのにかかる時間を短縮します。
data_frame <- fread("filename.csv",sep=",",header=FALSE,stringsAsFactors=FALSE,select=c(1,4,5,6,7),colClasses=c("as.numeric","as.character","as.numeric","as.Date","as.Factor"))