Comment trouver des éléments communs à partir de plusieurs vecteurs?

159

Quelqu'un peut-il me dire comment trouver les éléments communs à partir de plusieurs vecteurs?

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

Je veux obtenir les éléments communs des vecteurs ci-dessus (ex: 3 et 9)

Chares
la source
45
Ce n'est pas une bonne idée d'utiliser ccomme nom de variable ...
Marek
4
pourquoi c'est une lettre comme les autres?
Mostafa
12
@DimitriPetrenko car vous pouvez déclarer des listes avec c(1,2...).
Mathias711

Réponses:

333

Il y a peut-être une manière plus intelligente de procéder, mais

intersect(intersect(a,b),c)

fera le travail.

EDIT: Plus intelligemment et plus facilement si vous avez beaucoup d'arguments:

Reduce(intersect, list(a,b,c))
bnaul
la source
16
+1 pour nous rappeler Reduceet la bonne capitalisation R!
mariotomo
8
Il est à noter que intersectc'est pour les opérations d'ensemble. Si vous avez des éléments récurrents dans les vecteurs, vous perdrez cette information car les vecteurs sont transformés en ensembles avant l'intersection. Par exemple, intersect(c(1,1,2,3), c(1,1,3,4))cela aboutirait c(1,3), et vous auriez peut-être voulu le résultat c(1,1,3).
Giora Simchoni
1
@GioraSimchoni comment pourriez-vous obtenir c (1,1,3), si c'est vraiment ce que vous voulez?
StatsSorceress
@StatsSorceress Supposons que vous vouliez "l'intersection préservant les doublons" de vecteurs constitués d'entiers positifs, tous dans une liste L. Le code suivant fonctionne: 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])))Une autre façon de faire cela consisterait à utiliser la matchfonction avec un indice négatif pour supprimer itérativement de chacun des vecteurs chaque élément ajouté au "noyau".
Montgomery Clift
24

Une bonne réponse déjà, mais il existe plusieurs autres façons de le faire:

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

ou,

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

Vous pouvez évidemment omettre les uniqueappels si vous savez qu'il n'y a pas de valeurs répétées dans a, bou c.

James
la source
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 Un code plus simple

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

intersect_all(a,b,c)
Abhishek K Baikady
la source