2016-10-05 11 views
1

大きなデータテーブルがあります。103a_fooが存在するかどうかを確認したいのですが。しかし、大きなテーブルのファイル名は別々に書かれているので、正規表現を使用する必要があります。大きなデータの列の部分文字列の最初の一致を見つけます。

dt = structure(list(myID = c("86577", "34005","34005", 
"194000", "30252", "71067"), 
filename = c("/scratch/tmpdir/12a_foo.mzXML.gz", 
"/scratch/tmpdir/103b_foo.XML.gz", "/scratch/tmpdir/103a_foo.XML.gz", 
"/scratch/tmpdir/103a_foo.XML.gz", 
"/scratch/tmpdir/100b_foo.XML.gz", "/scratch/tmpdir/108a_foo.XML.gz")), 
class = c("data.table", "data.frame"), 
row.names = c(NA, -5L), 
.Names = c("myID", "filename")) 

出力として、インデックスが3になります。これは初めて発生するためです。私はgrep('103a_foo', dt$filename)[1]を使用していましたが、テーブルが大きい(1,000万行)ので、最初の発生時に検索を停止します。

答えて

6

fixed = TRUEに設定すると、それほど時間がかかりません。本当にあなたのニーズには遅すぎますか?私の知る限り

x <- sample(dt$filename, 1e7, TRUE) 
library(microbenchmark) 
microbenchmark(grep('103a_foo', x), 
       grep('103a_foo',dt$filename, fixed = TRUE), 
       times = 5) 

#Unit: milliseconds 
#        expr  min  lq  mean #median  uq  max neval cld 
#    grep("103a_foo", x) 2124.8178 2125.707 2128.7849 2127.542 2128.2054 2137.6532  5 b 
# grep("103a_foo", x, fixed = TRUE) 826.2298 826.597 832.7058 829.969 840.1974 840.5359  5 

、あなたは多くの場合、これを必要とする場合は、Rcppを使用することができ、純粋なRを使用してベクトル化ループの外に壊しgrepを実装するいかなる効率的な方法はありません。

+0

私は103a_fooが実際の正規表現OPを使用しているかどうか疑います。 –

+1

@WiktorStribiżewOPは、彼女が実際に正規表現を必要としていることを示すものではありません。彼女のプロフィールに基づいて、TACGという文字の特定のシーケンスを検索するかもしれない。 – Roland

+0

これにRcppを使用する場合は、http://gallery.rcpp.org/articles/boost-regular-expressions/を参照してください。 – Roland

2

@Rolandはgrepで指摘したように、最初の試合では停止できません。しかし、あなたが頻繁に記述した操作を行う必要がある場合は、あなたが見ようとしているすべての "ベース名"を一度抽出してからmatch(最初のオカレンスで実際に破損する)を使用すると役に立ちます。次のようなものがあります:

#this line might not work depending on the actual format of your real data 
basenames<-gsub("^.*/|\\..*$","",dt$filename) 
#then we use match 
match("103a_foo",basenames) 
#[1] 3 
関連する問題