209

Can anyone tell me how to find the common elements from multiple vectors?

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

I want to get the common elements from the above vectors (ex: 3 and 9)

zx8754
  • 52,746
  • 12
  • 114
  • 209
Chares
  • 2,753
  • 3
  • 17
  • 7

3 Answers3

435

There might be a cleverer way to go about this, but

intersect(intersect(a,b),c)

will do the job.

EDIT: More cleverly, and more conveniently if you have a lot of arguments:

Reduce(intersect, list(a,b,c))
bnaul
  • 17,288
  • 4
  • 32
  • 30
  • 24
    +1 for reminding us about `Reduce` and the correct R capitalization! – mariotomo Aug 12 '11 at 12:01
  • 9
    It is worth noting that `intersect` is for set operations. If you have elements recurring in the vectors, you will lose this info because the vectors are turned into sets prior to intersect. E.g. `intersect(c(1,1,2,3), c(1,1,3,4))` would result in `c(1,3)`, and you might have wanted the result `c(1,1,3)`. – Giora Simchoni Oct 13 '16 at 12:59
  • 2
    @GioraSimchoni how could you get c(1,1,3), if that is really what you want? – StatsSorceress Aug 25 '18 at 18:01
  • @StatsSorceress Suppose you want the "intersection preserving duplicates" of vectors consisting of positive integers, all in a list L. The following code works: `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])))` Another way to do this would use the `match` function along with negative subscripting to iteratively remove from each of the vectors every element added to the "kernel". – Montgomery Clift Oct 03 '19 at 08:05
28

A good answer already, but there are a couple of other ways to do this:

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

or,

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

You can obviously omit the unique calls if you know that there are no repeated values within a, b or c.

James
  • 65,548
  • 14
  • 155
  • 193
  • how can i find common elements across different column in a single dataframe the element are numeric i tried the reduce function not outout i tried converting them into factor still no answer but if i try one by such as intersect(df$a,df$b) etc working ..since i have a total of 40 columns it cumbersome to do it ...can you suggest something shorter – kcm Sep 11 '20 at 21:05
10
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 A simpler code

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

intersect_all(a,b,c)