ベクトルの要素のインデックスを見つけるためのR関数はありますか?


324

Rでは、要素xとベクトルがありvます。にv等しい要素の最初のインデックスを見つけたいのですがx。これを行う方法の1つは次のとおりwhich(x == v)[[1]]です。それを行うためのより直接的な方法はありますか?

ボーナスポイントについてx、ベクトルなら機能する機能はありますか?つまり、xin の各要素の位置を示すインデックスのベクトルを返す必要がありvます。


Rはベクトルで動作するwhich(x == v)[[1]]ように最適化されているため、それほど効率的ではありません。これは==、すべてのベクトル要素に適用される1つの比較()演算子と、インデックス(which)の1つのサブセットです。それでおしまい。この関数で10.000回の繰り返しを実行していない限り、関連性のあるものは何もありません。その他のソリューションではmatch、などのPosition多くのデータが返されない場合がありwhichますが、必ずしも効率的ではありません。
BurninLeo

2
私の質問では、xではwhich(x == v)[[1]]なくベクトル化された関数を使用したいと思いましたが、そうではありません。
ライアンC.トンプソン

回答:


461

この関数matchはベクトルに対して機能します。

x <- sample(1:10)
x
# [1]  4  5  9  3  8  1  6 10  7  2
match(c(4,8),x)
# [1] 1 5

match要求したとおり、最初に一致したものだけを返します。最初の引数の値の2番目の引数の位置を返します。

複数のマッチングについて%in%は、行く方法です:

x <- sample(1:4,10,replace=TRUE)
x
# [1] 3 4 3 3 2 3 1 1 2 2
which(x %in% c(2,4))
# [1]  2  5  9 10

%in%最初の引数と同じ長さの論理ベクトルを返します。TRUEその値が2番目の引数にあるFALSE場合はa、それ以外の場合はです。


matchと%in%の両方を含むc(2,3,3)とc(1,2,3,4)の例は、例の間の変更が少ないため、より有益になると思います。match(c(2,3,3)、c(1:4))は、which(c(2,3,3)%in%c(1:4))から異なる結果を返しますが、最初のベクトルを長くする必要はありません。例から例への多くの変更。また、非一致を非常に異なる方法で処理することにも注意してください。
ジョン、

1
@ジョン:それはすべて本当ですが、それはOPが尋ねたものではありません。OPは、長いベクトルから始めて、別のベクトルで指定された要素の最初の一致を見つけるように求めました。完全を期すために、すべてのインデックスに関心がある場合はwhich(%in%)を使用する必要があることを付け加えました。ところで、あなたの答えを削除する理由はありません。有効な情報です。
Joris Meys、2011

1
match最初の発生のインデックスが必要な場合は、問題の引数の順序が重要であることを強調すると役立つと思います。あなたの例でmatch(x,c(4,8))は、さまざまな結果が得られますが、最初はそれほど明白ではありません。
apitsch 2017年

@goldenoslikのヘルプページを読むと役立ちますmatch。それはすべてそこで説明されています。しかし、その情報を追加しました。
Joris Meys 2017年

ありがとう!この解決策は私の日を救った!
金華王

26

Positionfunprog {base} の関数も機能します。任意の関数を渡すことができ、最初または最後の一致を返します。

Position(f, x, right = FALSE, nomatch = NA_integer)


10

上記の方法の効率についての小さなメモ:

 library(microbenchmark)

  microbenchmark(
    which("Feb" == month.abb)[[1]],
    which(month.abb %in% "Feb"))

  Unit: nanoseconds
   min     lq    mean median     uq  max neval
   891  979.0 1098.00   1031 1135.5 3693   100
   1052 1175.5 1339.74   1235 1390.0 7399  100

だから、最高のものは

    which("Feb" == month.abb)[[1]]

ベンチマークは長さ12のベクトルに基づいているため、意味がありません。また、あなたの例でwhich("Feb" == month.abb)は– 2理由を返します[[1]]か?
マーカス

@markusこのコードwhich( "Feb" == month.abb)[[1]]は "2"を返し、このコードwhich(month.abb%in% "Feb")も "2"を返します。また、なぜベクトルを使用しても意味がないのか不明
Andrii

1
それはベクトルについてではなく、その長さについてです。適切な長さのベクトルを生成し、それに基づいてベンチマークを行う必要があります。OPからの引用「これを行う1つの方法は: which(x == v)[[1]]ですが、それは非常に非効率的であるようです」
マーカス

-5

Rは==、ベクトルhaystack内の針のインデックスを見つける方法で、二重の等号演算子をオーバーロードしました。これは、干し草の山での各一致の値をlogical含むベクトルを生成しTRUEます。

例:

haystack <- c(1, 2, 4, 3, 4)
needle <- 4
indices <- needle == haystack
indices
[1] 3  5
haystack[indices]
[1] 4  4

両方がベクターの場合に機能し、複数のベクターを使用するように拡張できます。


2
==オペレータは、すでに針のベクトルでは動作しない非効率的な解決策として、私の質問で述べました。
ライアンC.トンプソン

「両方がベクトルである場合に機能します」-おそらく、あなたが何を意味するかによって...しかし、OPが望んでいた意味ではありません。
フランク

30
FALSE FALSE TRUE FALSE TRUEこの例では、インデックスの代わりに取得します
Sashko Lykhenko '31 / 10/31

6
これをRで実行したことは==ありません。インデックスではなく論理ベクトルを返します。そのためwhich()には、7年前に説明したように、が必要です。
Joris Meys、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.