2012-11-26 14 views
6

単一のマルチコアマシン上の1つのテキストファイルに対して、Rと並行して反復することは可能ですか?コンテキストの場合、テキストファイルは250〜400MBのJSON出力の間にあります。R内で並列にreadLinesを実行することができます。

EDIT:

は、ここで私はで遊んでてきたいくつかのコードサンプルです。私の驚いたことに、並列処理は勝利しませんでした - ただ基本的なlapply - しかし、これは私の部分でユーザーのエラーが原因である可能性があります。さらに、多数の大きなファイルを読み込もうとすると、私のマシンが息を吹きました。ここ

## test on first 100 rows of 1 twitter file 
library(rjson) 
library(parallel) 
library(foreach) 
library(plyr) 
N = 100 
library(rbenchmark) 
mc.cores <- detectCores() 
benchmark(lapply(readLines(FILE, n=N, warn=FALSE), fromJSON), 
      llply(readLines(FILE, n=N, warn=FALSE), fromJSON), 
      mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON), 
      mclapply(readLines(FILE, n=N, warn=FALSE), fromJSON, 
        mc.cores=mc.cores), 
      foreach(x=readLines(FILE, n=N, warn=FALSE)) %do% fromJSON(x), 
      replications=100) 

は、2番目のコードサンプルによる非平行ファイル・システムIOの性質readLines()とおそらく

parseData <- function(x) { 
    x <- tryCatch(fromJSON(x), 
       error=function(e) return(list()) 
       ) 
    ## need to do a test to see if valid data, if so ,save out the files 
    if (!is.null(x$id_str)) { 
    x$created_at <- strptime(x$created_at,"%a %b %e %H:%M:%S %z %Y") 
    fname <- paste("rdata/", 
        format(x$created_at, "%m"), 
        format(x$created_at, "%d"), 
        format(x$created_at, "%Y"), 
        "_", 
        x$id_str, 
        sep="") 
    saveRDS(x, fname) 
    rm(x, fname) 
    gc(verbose=FALSE) 
    } 
} 

t3 <- system.time(lapply(readLines(FILES[1], n=-1, warn=FALSE), parseData)) 
+0

JSONファイルの読み込みやJSONファイルの解析で問題がありますか? –

+0

どちらもありません。単純なforループを使用しようとすると、私のマシンは最終的にフリーズします。私は、各JSONエントリに対して関数を実行しようとしました。別のrdsファイルを読み込んで保存するなど、すべてのオプションで、メモリ使用量を意識し、可能な限り最適化と消去を試みました。いくつかのアイデアはひどいものでしたが、最終的には、Base Rだけで大きなデータセットを「分析」する方法を見つけ出し、現時点ではより良いソリューションが存在するという事実を無視しています。 – Btibert3

+0

再現可能な例は、私たちがフィードバックを提供することをはるかに簡単にします。 –

答えて

7

答えは何に依存します問題は実際にはファイルを並行して読むこと、またはファイルを並行して処理することです。

並列

で読書あなたは、例えば、複数の入力ファイルにJSONファイルを分割し、それらを並行して読むことができますパラレルバックエンドと組み合わせplyrの機能を使用して:

result = ldply(list.files(pattern = ".json"), readJSON, .parallel = TRUE) 

バックエンドを登録すると、おそらく今ベースR.に統合されてparallelパッケージを使用して行うことができますまたはあなたは、doSNOWパッケージを使用する詳細については、this post on my blog見ることができます。パラレル

処理このシナリオでは、あなたの最善の策は、文字のベクターにデータセット全体を読み取られたデータを分割して、例えばと組み合わせたパラレルバックエンドを使用することですplyrの機能です。

+1

悪い考えではありません。ファイルを分割する方法を探しているなら、UNIXの 'split'コマンドを見てください。 –

+0

Linuxコマンドは常に良い解決策です;) –

+0

@JeffAllen面白いです。事前にコマンドを使ってデータを事前処理することは考えていませんでした。コマンドラインの専門家ではありませんが、私が周回するほど、いくつかのコマンドがどれほど強力であるかがわかります。 – Btibert3

2

ありません。もちろん、パラレルNFSなどを使用している場合は、この制限は適用されません。しかし、あなたが「標準」アーキテクチャを採用していると仮定すると、readLine()呼び出しを並列化することは実現できません。

あなたの最善の策は、おそらく500メガバイトは、おそらくあなたがオブジェクトがすでに読み込まれている後に、処理を並列化、その後、メモリに収まる<として見てファイル全体を読み込むことであろう。

+0

+1ですが、ちょっとした作業では、与えられたファイル接続から読み込む必要がある行番号を各ワーカーに割り当てることによって、 'readLines'と並行して読むことができます。 –

+0

@PaulHiemstraあなたはその可能性が最も単純なケースでどのように行われるかの例を挙げることができますか? :) –

+0

@AnthonyDamico私は今は時間がありませんが、それは簡単ではないと思うし、うまく動作しないかもしれません。 –

関連する問題