2016-11-29 18 views
0

データフレームの各行に関するベクトルの各要素の文字列一致の数を数えるrのループを最適化しようとしています。小さなデータセットでは、それはかなり良い(〜15分、11列、914行)。しかし、巨大なデータセット(914列、18000行)で動作するには数日かかる。rループの文字列の一致を高速化する(ベクトルとデータ。フレーム)

このループを他の手法(ベクトル化など)を使って最適化する方法を知っている人はいませんか?どんな解決策も大いにありがとう!

更新 ここに小さなデータセットがあります。それは最速ここ

df<-data.frame(replicate(10,sample(c("sp1", "sp2"),10,rep=TRUE))) 
vec<-c("sp1", "sp2") 
richa <- data.frame() 

    for (j in 1:length(vec)){ 
    for (i in 1:dim(df)[1]){ 
    richa[i,j] <- length(df[i,][df[i,] == vec[j] ]) 
    } 
    } 
+1

はい、私はおそらくこれを行う方法を知っています。テストのための最小限の再現可能な例を提供してください。 – Roland

+0

ありがとう!ここには2つのファイルがあります:https://www.dropbox.com/s/vvksp7c1kerqjbq/pddbnh.csv?dl=0 https://www.dropbox.com/s/zjt9shku0gjf03t/pidf.csv?dl=0 – CristianR

+0

(forループのパフォーマンスを改善するためのQ&Aがたくさんあるので、明らかにSOの完全な検索はまだ行っていません)[[pidf [i、] == row.names(pddbnh)を処理する[ j]] 'が失敗するようになるだろう。その引数の結果は強制的に0または1になります(長さ0の置換に関するエラーが表示されるはずです)。たぶんあなたは実際に何をしようとしているのかを説明する必要があります。 –

答えて

3

1は、(さらに高速については下記を参照)lapplyを利用する方法です。

richa <- lapply(X = vec, FUN = function(x) rowSums(df == x)) 
richa <- do.call(cbind, richa) 

迅速microbenchmarkを小さなデータセットに対してこのご比べて約10倍の高速化に番組を提供してきましたforループメソッド。

parallel::mclapplyまたはplyr::laplyparallel = TRUE)のいずれかを使用して、これを追加するだけで簡単にマルチスレッド化することもできます。これは少し余分な作業が必要ですが、あなたが持っている18000 x 914のデータセットには価値があるかもしれません。

編集する:私はRcppを勉強しているので、そこに行くループがいくつかあるので、ここではRcppを使ったさらに高速な解決策があります。ここで(一度にコンパイルする必要があります)関数の定義です:

Rcpp::cppFunction(' IntegerMatrix charCrossCheck(CharacterMatrix df, 
          CharacterVector vec) { 

       IntegerMatrix output(df.nrow(), vec.size()); 

       for (int j=0; j < vec.size(); ++j){ 
        for (int i=0; i < df.nrow(); ++i){ 
         int count = 0; 
         for(int k=0; k < df.ncol(); k++){ 
          if(df(i,k) == vec[j]) { 
           count++; 
          } 
         } 
         output(i,j) = count; 
        } 
       } 
       return output; 

       } ') 

は次にあなたがその関数を呼び出すことができます。

richa <- charCrossCheck(as.matrix(df), vec) 

Rcppはここに非常に高速です。あなたの非常に小さなサンプル上のマイクロベンチマークはdfサイズ4000x4000に出入力データを拡大し、

興味深いことにR.でのごforループよりも、それは上記の私のlapplyソリューションよりも速く3倍以上、約38Xより速く示し、vecの長さ10の場合、Rcpplapplyの両方の方法で非常に似た時間で完了します(それぞれ3.4秒と3.9秒)。あなたが言及したデータセット(18000行×914列、vecの長さ2)では、両方の解決法は1秒未満です。いずれにしても悪くない!

+0

両方の方法がかなり高速です!それは驚くべきことであり、私をたくさん助けてくれます。両方の実装の詳細を理解しようとします。私は驚いている! – CristianR

+0

@CristianR素晴らしい!あなたの問題を解決するのに役立ちましたら、回答を受け入れたものとしてマークしてください。 – rosscova

関連する問題