1は、(さらに高速については下記を参照)lapply
を利用する方法です。
richa <- lapply(X = vec, FUN = function(x) rowSums(df == x))
richa <- do.call(cbind, richa)
迅速microbenchmark
を小さなデータセットに対してこのご比べて約10倍の高速化に番組を提供してきましたfor
ループメソッド。
parallel::mclapply
またはplyr::laply
(parallel = 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の場合、Rcpp
とlapply
の両方の方法で非常に似た時間で完了します(それぞれ3.4秒と3.9秒)。あなたが言及したデータセット(18000行×914列、vec
の長さ2)では、両方の解決法は1秒未満です。いずれにしても悪くない!
はい、私はおそらくこれを行う方法を知っています。テストのための最小限の再現可能な例を提供してください。 – Roland
ありがとう!ここには2つのファイルがあります:https://www.dropbox.com/s/vvksp7c1kerqjbq/pddbnh.csv?dl=0 https://www.dropbox.com/s/zjt9shku0gjf03t/pidf.csv?dl=0 – CristianR
(forループのパフォーマンスを改善するためのQ&Aがたくさんあるので、明らかにSOの完全な検索はまだ行っていません)[[pidf [i、] == row.names(pddbnh)を処理する[ j]] 'が失敗するようになるだろう。その引数の結果は強制的に0または1になります(長さ0の置換に関するエラーが表示されるはずです)。たぶんあなたは実際に何をしようとしているのかを説明する必要があります。 –