Jak znaleźć wspólne elementy z wielu wektorów?


159

Czy ktoś może mi powiedzieć, jak znaleźć wspólne elementy z wielu wektorów?

a <- c(1,3,5,7,9)
b <- c(3,6,8,9,10)
c <- c(2,3,4,5,7,9)

Chcę uzyskać wspólne elementy z powyższych wektorów (np: 3 i 9)


45
Nie jest dobrym pomysłem używanie cjako nazwy zmiennej ...
Marek

4
dlaczego to list jak inne?
Mostafa

12
@DimitriPetrenko, ponieważ możesz deklarować listy za pomocą c(1,2...).
Mathias711,

Odpowiedzi:


333

Może istnieć sprytniejszy sposób, aby to zrobić, ale

intersect(intersect(a,b),c)

wykona robotę.

EDYCJA: Sprytniej i wygodniej, jeśli masz dużo argumentów:

Reduce(intersect, list(a,b,c))

16
+1 za przypomnienie nam o Reducei poprawne użycie wielkich liter w R.
mariotomo

8
Warto zauważyć, że dotyczy intersectto operacji na zbiorach. Jeśli masz elementy powtarzające się w wektorach, utracisz tę informację, ponieważ wektory zostaną zamienione w zbiory przed przecięciem. Np intersect(c(1,1,2,3), c(1,1,3,4))spowodowałoby c(1,3), a może nie chciał wynik c(1,1,3).
Giora Simchoni

1
@GioraSimchoni, jak możesz uzyskać c (1,1,3), jeśli naprawdę tego chcesz?
StatsSorceress

@StatsSorceress Załóżmy, że chcesz "przecięcie zachowujące duplikaty" wektorów składających się z dodatnich liczb całkowitych, wszystkie na liście L. Następujący kod działa: N <- max(unlist(L)); LT <- lapply(L, tabulate, nbins = N); v <- do.call(pmin, LT); unlist(sapply(1:N, function(x) rep(x, v[x])))Innym sposobem na zrobienie tego byłoby użycie matchfunkcji wraz z ujemnym indeksowaniem do iteracyjnego usuwania z każdego z wektorów każdy element dodany do "jądra".
Montgomery Clift

24

To już dobra odpowiedź, ale można to zrobić na kilka innych sposobów:

unique(c[c%in%a[a%in%b]])

lub,

tst <- c(unique(a),unique(b),unique(c))
tst <- tst[duplicated(tst)]
tst[duplicated(tst)]

Można oczywiście pominąć uniquepołączeń, jeśli wiesz, że nie ma powtarzających się wartości ciągu a, blub c.


7
intersect_all <- function(a,b,...){
  all_data <- c(a,b,...)
  require(plyr)
  count_data<- length(list(a,b,...))
  freq_dist <- count(all_data)
  intersect_data <- freq_dist[which(freq_dist$freq==count_data),"x"]
  intersect_data
}


intersect_all(a,b,c)

UPDATE EDIT Prostszy kod

intersect_all <- function(a,b,...){
  Reduce(intersect, list(a,b,...))
}

intersect_all(a,b,c)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.