2016-08-19 2 views
2

OKを迷子に、私は私がwhichgrepl(代替案は歓迎されている)で解決することができると信じて少し問題を抱えているが、私は迷子になっています:がその使用中に()とRで正規表現

my_query<- c('g1', 'g2', 'g3') 
my_data<- c('string2','string4','string5','string6') 

my_queryのインデックスをmy_dataに戻したいと思います。上記の例では、 'g2'のみがmydataにあるので、例の結果は2になります。助けてください:)

+1

「sapply(my_query、grepl、x = my_data)」、「sapply(my_query、grepl、x = my_data)」のアイデア。あなたは 'which()'に2番目のものをラップすることができます。 – Gregor

+0

ありがとう、グレゴール。私は2つの例が同じだと思う。また、それは私に行列を返します。私が考える行列の列番号を取得するには、そのような方法でそれをラップする必要があります。 – madmaxthc

+1

残念ですが、2番目は 'sapply(my_query、function(q)任意の(grepl(q、my_data))) 'につながる任意の(grepl(q、my_data)))'を返します。しかし、多かれ少なかれZheyuanが投稿したもの。 – Gregor

答えて

5

ループなしでこれを行う簡単な方法はないようです。 my_query内の各要素について、我々はTRUEまたはFALSEを取得するには、以下の機能のいずれかを使用することができます。

f1 <- function (pattern, x) length(grep(pattern, x)) > 0L 

f2 <- function (pattern, x) any(grepl(pattern, x)) 

例えば、

f1(my_query[1], my_data) 
# [1] FALSE 
f2(my_query[1], my_data) 
# [1] FALSE 

はその後、我々が適用する*applyループを使用して、すべてにf2を言いますmy_queryの要素:

which(unlist(lapply(my_query, f2, x = my_data))) 
# [1] 2 

ありがとうございます、それはうまくいくようです。正直言って、私はあなたのワンラインオリジナルのバージョンを好みました。 *applyで後で呼び出す別の関数を作成して編集した理由がわかりません。 which(lengths(lapply(my_query, grep, my_data)) > 0L)と比較して利点はありますか?

まあ、私は完全にはわかりません。私は?lengthsを読んだとき:

One advantage of ‘lengths(x)’ is its use as a more efficient 
version of ‘sapply(x, length)’ and similar ‘*apply’ calls to 
‘length’. 

私はどのように、はるかに効率的lengthssapplyと比較されていることを知りません。とにかく、それがまだループの場合、私の元の提案which(lengths(lapply(my_query, grep, my_data)) > 0L)は2つのループを実行しています。私の編集は基本的に2つのループを組み合わせています。

あなたはまだ、単一のラインに私の新しい編集を手配することができます。コメントを拡張し

which(unlist(lapply(my_query, function (pattern, x) any(grepl(pattern, x)), x = my_data))) 

または

which(unlist(lapply(my_query, function (pattern) any(grepl(pattern, my_data))))) 
+0

ありがとう、Zheyuan李、それは動作するようです。正直言って、私はあなたの1ライナーのオリジナルバージョンを好んだ;)なぜあなたは* applyで後で呼び出す別の関数を作成して編集したのか分からない。 "which(lengths(lapply(my_query、grep、my_data))> 0)"と比較して利点はありますか? – madmaxthc

2

は、あなたが試みることができる@Gregorによって最初に掲示さ:

which(colSums(sapply(my_query, grepl, my_data)) > 0) 
#g2 
# 2 

関数colSumsはベクトル化されており、パフォーマンスの面で問題はありません。 sapply()ループは、クエリベクトル内の各要素をチェックする必要があるため、避けられないようです。ループの結果は論理行列であり、各列はmy_queryの要素を表し、各行はmy_dataの要素を表します。この行列をwhich(colSums(..) > 0)にラップすることにより、少なくとも1つのTRUEを含むすべての列のインデックス番号、すなわちmy_dataのエントリを有する一致が得られる。

+0

さて、あなたは 'sapply'を避けることができます:' r = regexpr(paste(my_query、collapse = "|")、my_data);マッチ(regmatches(my_data、r)、my_query) ' – Frank

+0

@Frank Interesting。この可能性を指摘してくれてありがとう。個人的にはやや複雑すぎますが、そこではループが使われていないのは事実です。少なくとも私は慎重な言葉遣い(「...避けられないと思われる)」を使用しましたが、コーディングには常に選択肢があることに気がつきました。別の答えでは、ネストされたループについての同様の解決策について議論が行われています( 'lengths'内の暗黙的なループのためです)。その意味で、 'colSums'と' grepl'との組み合わせは、私の良い選択肢のように見えます。 – RHertel

+2

ええ、ここであなたのアプローチを使用すると思います。なぜなら、私は正規表現のトリックに大きく傾いているのが好きではないからです。 – Frank