Come trovare elementi comuni da più vettori?


159

Qualcuno può dirmi come trovare gli elementi comuni da più vettori?

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

Voglio ottenere gli elementi comuni dai vettori sopra (es: 3 e 9)


45
Non è una buona idea usare ccome nome variabile ...
Marek,

4
perché è una lettera come le altre?
Mostafa,

12
@DimitriPetrenko perché puoi dichiarare elenchi con c(1,2...).
Mathias711,

Risposte:


333

Potrebbe esserci un modo più intelligente per farlo, ma

intersect(intersect(a,b),c)

farà il lavoro.

EDIT: più intelligente e più conveniente se hai molti argomenti:

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

16
+1 per ricordarci Reducee la corretta R maiuscola!
mariotomo,

8
Vale la pena notare che intersectè per le operazioni impostate. Se hai elementi ricorrenti nei vettori, perderai queste informazioni perché i vettori vengono trasformati in set prima dell'intersezione. Ad esempio intersect(c(1,1,2,3), c(1,1,3,4))si tradurrebbe in c(1,3), e potresti aver desiderato il risultato c(1,1,3).
Giora Simchoni,

1
@GioraSimchoni come hai potuto ottenere c (1,1,3), se è davvero quello che vuoi?
StatsSorceress

@StatsSorceress Supponiamo che tu voglia "l'intersezione che preserva i duplicati" di vettori costituiti da numeri interi positivi, tutti in un elenco L. Il seguente codice funziona: 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])))Un altro modo per fare questo sarebbe utilizzare la matchfunzione insieme alla sottoscrizione negativa per rimuovere iterativamente da ciascuno dei vettori ogni elemento aggiunto al "kernel".
Montgomery Clift,

24

Una buona risposta già, ma ci sono un paio di altri modi per farlo:

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

o,

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

È ovviamente possibile omettere le uniquechiamate se si sa che ci sono valori non ripetuti all'interno a, bo 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)

AGGIORNA MODIFICA Un codice più semplice

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

intersect_all(a,b,c)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.