2015-05-07 4 views
6

Hier habe ich zwei String-Vektoren, deren Reihenfolge wichtig ist und nicht geändert werden kann.R Vektor-Vektor-Matching mit geordneten Indizes

vec1 <- c("carrot","carrot","carrot","apple","apple","mango","mango","cherry","cherry") 
vec2 <- c("cherry","apple") 

Ich möchte herausfinden, ob Elemente in vec2 in vec1 erscheint und wenn ja, wo (Index/Position) und in welcher Reihenfolge.

Ich versuchte which(vec1 %in% vec2), die 4 5 8 9 gibt. Dies sind korrekte Indizes, aber in der falschen Reihenfolge. Ich versuchte match(vec2,vec1), die 8 4 gibt. Nur die erste Übereinstimmung wird zurückgegeben. Dies würde funktionieren, wenn vec1 einmalig wäre.

Idealerweise suche ich nach diesem Ergebnis: 8 9 4 5. Kirsche ist zuerst an Position 8 und 9 und dann Apfel ist abgestimmt auf 4 und 5.

Gibt es eine kluge Möglichkeit, dies ohne Rückgriff auf Schleifen tun?

Antwort

11

können Sie versuchen, diese

unlist(lapply(vec2, function(x) which(vec1 %in% x))) 
[1] 8 9 4 5 

, die in vec2 nacheinander nacheinander die Elemente in vec1 Gegenwart zurückkehren.

1

which(!is.na(match(vec1,vec2)))[order(match(vec1,vec2)[!is.na(match(vec1,vec2))])]

Wow ... es ist wahrscheinlich ein einfacher Weg, dies zu tun, aber ...

> match(vec1,vec2) 
[1] NA NA NA 2 2 NA NA 1 1 

OK, also durch das Spiel umzukehren, kann ich which() den Index zu bekommen, wo es ist nicht NA

> which(!is.na(match(vec1,vec2))) 
[1] 4 5 8 9 

Dies ruft die gewünschten Indizes auf, aber nicht in der von Ihnen gewünschten Reihenfolge. Also, wenn wir order auf dem match() Vektor verwenden, kann ich mich auf den gewünschten Wert neu sortieren lassen. Hier passe ich wieder zusammen und behalte nur die Nicht-NA-Werte bei.

> order(match(vec1,vec2)[!is.na(match(vec1,vec2))]) 
[1] 3 4 1 2 

Subsort durch diese und Sie erhalten:

> which(!is.na(match(vec1,vec2)))[order(match(vec1,vec2)[!is.na(match(vec1,vec2))])] 
[1] 8 9 4 5 

Wenn diese langsam ist, speichern Sie die Match-Anweisung zuerst nicht über und immer wieder tun.