Bir vektördeki bir elemanın indeksini bulmak için bir R fonksiyonu var mı?


324

R'de bir elementim xve bir vektörüm var v. Ben bir elemanın ilk indeksini bulmak istiyorum vo eşittir x. Bunu yapmanın bir yolu olduğunu biliyorum: which(x == v)[[1]]ama bu aşırı verimsiz görünüyor. Bunu yapmanın daha doğrudan bir yolu var mı?

Bonus puanlar için, xbir vektör ise çalışan bir işlev var mı? Olduğuna göre, her bir elemanının konumunu gösteren indekslerinin bir vektör döndürmelidir xiçinde v.


R vektörlerle çalışmak için optimize edildiğinden, which(x == v)[[1]]çok verimsiz değildir. ==Tüm vektör öğelerine uygulanan bir karşılaştırma ( ) operatörü ve indeksler ( which) üzerinde bir alt kümedir . Bu kadar. Bu işlevde 10.000 tekrarlama yapmadığınız sürece bununla ilgili bir şey yok. Diğer çözümler gibi matchve Positionçok fazla veri döndürmeyebilir which, ancak bunların daha verimli olması gerekmez.
BurninLeo

2
Sorum, x üzerinde vektörize edilmiş olan ve which(x == v)[[1]]olmayan bir işlevi tercih edeceğimi belirtti .
Ryan C. Thompson

Yanıtlar:


461

Fonksiyon matchvektörler üzerinde çalışır:

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

matchsadece bir maçın ilk karşılaşmasını istediğiniz gibi döndürür. İlk bağımsız değişkendeki değerlerin ikinci bağımsız değişkenindeki konumu döndürür.

Birden fazla eşleme %in%için, gitmenin yolu:

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%ilk bağımsız değişken olduğu sürece mantıksal bir vektör döndürür; TRUEbu değer ikinci bağımsız değişkende bir if ve başka bir değer bulunabilir FALSE.


Hem eşleşme hem de% olarak% ile c (2,3,3) ve c (1,2,3,4) içeren bir örnek, örnekler arasında daha az değişiklik olduğunda daha öğretici olacaktır. eşleşme (c (2,3,3), c (1: 4)), daha uzun bir ilk vektöre ihtiyaç duymadan (% c (1: 4)% c (1: 4)%) örnekten örneğe birçok değişiklik. Ayrıca, eşleşmeleri çok farklı ele aldıklarını belirtmek gerekir.
John

1
@John: hepsi doğru, ama OP'nin sorduğu şey bu değil. OP, uzun bir vektörden başlayarak, başka birinde verilen elementlerin ilk eşleşmesini bulmasını istedi. Ve tamlık için, tüm endekslerle ilgileniyorsanız, hangisini (% olarak%) kullanmanız gerektiğini ekledim. BTW, cevabınızı silmek için bir neden yok. Geçerli bilgi.
Joris Meys

1
matchİlk oluşumun indeksini istiyorsanız, argümanların sırasının önemli olduğunu vurgulamak yararlı olacaktır . Örneğin match(x,c(4,8)), ilk başta çok açık olmayan farklı sonuçlar verir.
apitsch

@goldenoslik Yardım sayfasını okursanız yardımcı olur match. Hepsi orada açıklandı. Ama bu bilgiyi ekledim.
Joris Meys

Teşekkürler! Bu çözüm günümü kurtardı!
Jinhua Wang

26

Positionfunprog {base} içindeki işlev de işi yapar. İsteğe bağlı bir işlevi geçirmenize olanak tanır ve ilk veya son eşleşmeyi döndürür.

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


10

Yukarıda belirtilen yöntemlerin etkinliği hakkında küçük bir not:

 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

Yani, en iyisi

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

Karşılaştırma ölçünüz, uzunluk 12 vektörünü temel alır ve bu nedenle anlamlı değildir. Ayrıca örnekte which("Feb" == month.abb)döner 2-Neden [[1]]?
markus

@markus ("Feb" == month.abb) [[1]] "2" döndüren bu kodu ve (% "Feb" içindeki month.abb%) da "2" döndürür. Ayrıca, vektör kullanmanın neden anlamlı olmadığı net değil
Andrii

1
Vektörle ilgili değil, uzunluğu ile ilgilidir. Uygun uzunlukta bir vektör oluşturmalı ve ardından buna göre bir kıyaslama yapmalısınız. OP soruya alıntı "Ben, bunu yapmanın bir yolu olduğunu biliyoruz: which(x == v)[[1]] , . Ama bu aşırı verimsiz görünmektedir"
markus

-5

R, çift eşittir ==operatörünü vektör samanlıkta bir iğnenin indeksini bulma yöntemiyle aşırı yükledi . Samanlıkta her eşleşme için değerler logicaliçeren bir vektör verir TRUE.

Misal:

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

Her ikisi de vektörse çalışır ve birden fazla vektör kullanmak için genişletilebilir.


2
==Operatör zaten iğnelerin bir vektör ile çalışmaz verimsiz çözüm olarak benim soru geçiyordu.
Ryan

"her ikisi de vektörse çalışır" - belki, ne demek istediğinize bağlı olarak ... ama OP'nin istediği anlamda değil.
Frank

30
Ben olsun FALSE FALSE TRUE FALSE TRUEyerine bu örnekte endeksleri
Sashko Lykhenko

6
Bunu R'de hiç çalıştırmadınız ==. Endeksleri değil mantıklı bir vektör döndürür. Bunun için which()7 yıl önce açıkladığım gibi ihtiyacınız var .
Joris Meys
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.