Как найти общие элементы из нескольких векторов?


159

Может кто-нибудь сказать мне, как найти общие элементы из нескольких векторов?

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

Я хочу получить общие элементы из приведенных выше векторов (например, 3 и 9)


45
Это не очень хорошая идея использовать в cкачестве имени переменной ...
Marek

4
почему это письмо как у других?
Мостафа

12
@DimitriPetrenko, потому что вы можете объявить списки с помощью c(1,2...).
Mathias711

Ответы:


333

Там может быть более умный способ сделать это, но

intersect(intersect(a,b),c)

сделаю работу.

РЕДАКТИРОВАТЬ: более умно и удобнее, если у вас много аргументов:

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

16
+1 за напоминание о Reduceправильной и заглавной букве R!
Мариотомо

8
Стоит отметить, что intersectэто для заданных операций. Если у вас есть элементы, повторяющиеся в векторах, вы потеряете эту информацию, потому что векторы преобразуются в наборы до пересечения. Например intersect(c(1,1,2,3), c(1,1,3,4)), результат c(1,3), и вы, возможно, хотели получить результат c(1,1,3).
Гиора Симчони

1
@GioraSimchoni как вы могли бы получить C (1,1,3), если это действительно то, что вы хотите?
StatsSorceress

@StatsSorceress Предположим, что вы хотите «дубликаты, сохраняющие пересечение» векторов, состоящих из положительных целых чисел, все в списке L. Работает следующий код: еще 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])))один способ сделать это - использовать matchфункцию вместе с отрицательной подпиской для итеративного удаления из каждого из векторов. каждый элемент добавляется в «ядро».
Монтгомери Клифт

24

Хороший ответ уже есть, но есть несколько других способов сделать это:

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

или,

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

Очевидно, что вы можете пропустить uniqueвызовы, если знаете, что в них нет повторяющихся значений a, bили 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)

ОБНОВЛЕНИЕ РЕДАКТИРОВАТЬ Более простой код

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

intersect_all(a,b,c)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.