web-dev-qa-db-ja.com

R巨大なcsvを読む

巨大なcsvファイルがあります。サイズは約9 GBです。 16 GBのRAMがあります。 page のアドバイスに従い、以下に実装しました。

If you get the error that R cannot allocate a vector of length x, close out of R and add the following line to the ``Target'' field: 
--max-vsize=500M 

それでも、以下のエラーと警告が表示されます。 9 GBのファイルをRに読み込むにはどうすればよいですか? R 64ビット3.3.1があり、rstudio 0.99.903のコマンドの下で実行しています。私はWindows Server 2012 R2標準、64ビットOSを持っています。

> memory.limit()
[1] 16383
> answer=read.csv("C:/Users/a-vs/results_20160291.csv")
Error: cannot allocate vector of size 500.0 Mb
In addition: There were 12 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
3: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
4: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
5: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
6: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
7: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
8: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
9: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
10: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
11: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
12: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update1

提案された回答に基づいた最初の試行

> thefile=fread("C:/Users/a-vs/results_20160291.csv", header = T)
Read 44099243 rows and 36 (of 36) columns from 9.399 GB file in 00:13:34
Warning messages:
1: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update2

提案された回答に基づく私の2回目の試みは以下の通りです

thefile2 <- read.csv.ffdf(file="C:/Users/a-vs/results_20160291.csv", header=TRUE, VERBOSE=TRUE, 
+                    first.rows=-1, next.rows=50000, colClasses=NA)
read.table.ffdf 1..
Error: cannot allocate vector of size 125.0 Mb
In addition: There were 14 warnings (use warnings() to see them)

データ全体を一度に分析できるように、このファイルを単一のオブジェクトに読み込むにはどうすればよいですか

------------------アップデート3

高価な機械を買いました。 10個のコアと256 GBのRAMがあります。これは最も効率的なソリューションではありませんが、少なくとも近い将来には機能します。私は以下の回答を見ましたが、それらが私の問題を解決するとは思いません:(私はこれらの回答に感謝します。マーケットバスケット分析を実行したいのですが、私のデータをRAMに保持する以外に方法はないと思います

19
user2543622

RAM割り当てをすべての16 GBに増やすことができるように、64ビットWindowsだけでなく64ビットRを使用していることを確認してください。

さらに、ファイルをチャンクで読み取ることができます。

file_in    <- file("in.csv","r")
chunk_size <- 100000 # choose the best size for you
x          <- readLines(file_in, n=chunk_size)

data.tableを使用すると、大きなファイルの読み取りと操作をより効率的に処理できます。

require(data.table)
fread("in.csv", header = T)

必要に応じて、ffを使用してストレージメモリを活用できます。

library("ff")
x <- read.csv.ffdf(file="file.csv", header=TRUE, VERBOSE=TRUE, 
                   first.rows=10000, next.rows=50000, colClasses=NA)
17
Hack-R

ディスク上の処理を活用して、オブジェクト全体をRのメモリに保持しないことを検討する必要がある場合があります。 1つのオプションは、適切なデータベースにデータを格納し、Rにアクセスさせることです。 dplyrは、リモートソースを処理できます(実際には、データベースにクエリを実行するSQLステートメントを書き込みます)。私はこれを小さな例(わずか17,500行)でテストしましたが、うまくいけば、要件に合わせてスケールアップできます。

SQLiteをインストールする

https://www.sqlite.org/download.html

新しいSQLiteデータベースにデータを入力します

  • 以下を_import.sql_という名前の新しいファイルに保存します

CREATE TABLE tableName (COL1, COL2, COL3, COL4); .separator , .import YOURDATA.csv tableName

はい、列名を自分で指定する必要があります(私はそう思います)が、必要に応じてここでもそれらの型を指定できます。もちろん、名前/データのどこかにコンマがある場合は機能しません。

  • コマンドラインを介してSQLiteデータベースにデータをインポートする

_sqlite3.exe BIGDATA.sqlite3 < import.sql_

SQLiteデータベースを指すdplyr

SQLiteを使用しているため、すべての依存関係はdplyrによってすでに処理されています。

library(dplyr) my_db <- src_sqlite("/PATH/TO/YOUR/DB/BIGDATA.sqlite3", create = FALSE) my_tbl <- tbl(my_db, "tableName")

探索的分析を行う

dplyrは、このデータソースのクエリに必要なSQLiteコマンドを書き込みます。それ以外の場合は、ローカルテーブルのように動作します。大きな例外は、行数を照会できないことです。

my_tbl %>% group_by(COL2) %>% summarise(meanVal = mean(COL3))

_#>  Source:   query [?? x 2]
#>  Database: sqlite 3.8.6 [/PATH/TO/YOUR/DB/BIGDATA.sqlite3]
#>  
#>         COL2    meanVal
#>        <chr>      <dbl>
#>  1      1979   15.26476
#>  2      1980   16.09677
#>  3      1981   15.83936
#>  4      1982   14.47380
#>  5      1983   15.36479
_
9

これは、お使いのコンピュータではできない場合があります。場合によっては、_data.table_は、対応する_.csv_よりも多くのスペースを使用します。

_DT <- data.table(x = sample(1:2,10000000,replace = T))
write.csv(DT, "test.csv") #29 MB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 40001072 bytes #40 MB
_

2つのOOMが大きい:

_DT <- data.table(x = sample(1:2,1000000000,replace = T))
write.csv(DT, "test.csv") #2.92 GB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 4000001072 bytes #4.00 GB
_

Rでオブジェクトを保存することには自然なオーバーヘッドがあります。これらの数値に基づいて、ファイルを読み取るときのおおよそ1.33の要素がありますが、これはデータによって異なります。たとえば、

  • x = sample(1:10000000,10000000,replace = T)は、係数を約2倍にします(R:csv)。

  • x = sample(c("foofoofoo","barbarbar"),10000000,replace = T)は、0.5倍の係数を提供します(R:csv)。

最大に基づいて、9GBファイルはRに格納するために、潜在的に18GBのメモリを必要とします。エラーメッセージに基づいて、割り当ての問題ではなく、ハードメモリの制約に直面している可能性がはるかに高くなります。したがって、チャックでファイルを読み取って統合するだけでは機能しません。分析とワークフローを分割する必要もあります。もう1つの方法は、SQLなどのインメモリツールを使用することです。

6
Chris

これはひどい習慣ですが、このデータの処理方法によっては、tooに悪くないはずです。 Rが使用できる最大メモリを変更するには、memory.limit(new)を呼び出します。ここで、newは、Rの新しい_memory.limit_ in[〜 #〜] mb [〜#〜]。ハードウェアの制約にぶつかると、ウィンドウがメモリをハードドライブにページングし始めます(最悪の事態ではありませんが、処理速度が大幅に低下します)。

これをサーバーバージョンのWindowsページングで実行している場合、通常のWindows 10とは(おそらく)動作が異なる可能性があります。サーバーOSはこれに合わせて最適化する必要があるため、より高速になるはずです。

2 GB(またはmemory.limit(memory.limit()*2))の行から始めてみてください。それよりもはるかに大きい場合は、プログラムが遅くなりすぎると思いますメモリに読み込まれると。その時点で、私はもう少し購入することをお勧めしますRAMまたはパーツで処理する方法を見つけること。

1
Adam

処理をテーブルに分割してみることができます。すべてを操作するのではなく、forループ内に操作全体を入れて、16、32、64、または必要な回数実行します。後で計算するために必要な値はすべて保存できます。これは他の投稿ほど速くはありませんが、間違いなく戻ってきます。

x = number_of_rows_in_file / CHUNK_SIZE
for (i in c(from = 1, to = x, by = 1)) {
    read.csv(con, nrows=CHUNK_SIZE,...)
}

お役に立てば幸いです。

0
Woody1193