¿Cómo encontrar elementos comunes de múltiples vectores?

159

¿Alguien puede decirme cómo encontrar los elementos comunes de múltiples vectores?

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

Quiero obtener los elementos comunes de los vectores anteriores (ej .: 3 y 9)

Chares
fuente
45
No es una buena idea usar ccomo nombre de variable ...
Marek
44
¿Por qué es una carta como otras?
Mostafa
12
@DimitriPetrenko porque puedes declarar listas con c(1,2...).
Mathias711

Respuestas:

333

Puede haber una forma más inteligente de hacerlo, pero

intersect(intersect(a,b),c)

Hará el trabajo.

EDITAR: de manera más inteligente y más conveniente si tiene muchos argumentos:

Reduce(intersect, list(a,b,c))
bnaul
fuente
16
¡+1 por recordarnos Reducey la correcta capitalización R!
mariotomo
8
Vale la pena señalar que intersectes para operaciones de configuración. Si tiene elementos recurrentes en los vectores, perderá esta información porque los vectores se convierten en conjuntos antes de la intersección. Por ejemplo, intersect(c(1,1,2,3), c(1,1,3,4))daría como resultado c(1,3), y es posible que haya querido el resultado c(1,1,3).
Giora Simchoni
1
@GioraSimchoni, ¿cómo podrías obtener c (1,1,3), si eso es realmente lo que quieres?
EstadísticasSorceress
@StatsSorceress Suponga que desea los "duplicados que preservan la intersección" de los vectores que consisten en enteros positivos, todos en una lista L. El siguiente código funciona: 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])))Otra forma de hacerlo sería usar la matchfunción junto con la suscripción negativa para eliminar iterativamente de cada uno de los vectores cada elemento agregado al "kernel".
Montgomery Clift
24

Una buena respuesta ya, pero hay un par de otras formas de hacerlo:

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

o,

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

Obviamente, puede omitir las uniquellamadas si sabe que no hay valores repetidos dentro de a, bo c.

James
fuente
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)

ACTUALIZAR EDITAR Un código más simple

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

intersect_all(a,b,c)
Abhishek K Baikady
fuente