2015-09-15 5 views
0

Скажем, у меня есть три списка,Как найти пересечение списков списков в R?

> a 
[[1]] 
    begin end 
    3  5 
    9  10 
    11 14 

[[2]] 
    begin end 
    3  7 
    14 18 
    19 24 

[[3]] 
    begin end 
    6  9 
    14 22 
    18 30 

То, что я пытаюсь найти это пересечение всех «начинаются» колонки, так что в этом случае желаемый результат будет что-то вроде

"3" "14" 

Я знаю решение, предлагаемое по адресу How to find common elements from multiple vectors?; однако это решение предполагает, что количество списков статично. Если количество списков, которые у меня есть, должно измениться (скажем, до 5 списков, каждый с похожим столбчатым макетом), как бы я нашел пересечение?

+0

'a [[1]]' не имеет 14 в 'begin'. Должен ли код учитывать как «начало», так и «конец»? – nico

+0

Хороший вопрос. Ответ - нет, так как я хочу ЛЮБОЕ пересечение. Поэтому, если хотя бы два списка используют один и тот же элемент в начале, это должно быть найдено. – rdevn00b

+0

Проблема с использованием rbind здесь в том, что мне нужно держать списки раздельными. После этого шага в программе мне нужно определить частоту элементов в каждом списке по отношению к тем, которые находятся в пересекаемом множестве. так, например, если столбец начала [[3]] содержит 3,3,7, тогда программа покажет, что частота 3 в списке 1 равна 1, 3 в списке 2 равна 1, а 3 в списке 3 - 2. – rdevn00b

ответ

0

Используя входные данные @ Нико ...

full <- do.call(rbind, lapply(seq_along(a), function(i) within(a[[i]], {g = i}))) 

res <- table(full[,c("begin","g")]) 

#  g 
# begin 1 2 3 
# 3 1 1 0 
# 6 0 0 1 
# 9 1 0 0 
# 11 1 0 0 
# 14 0 1 1 
# 18 0 0 1 
# 19 0 1 0 

Строки уникальные значения begin и столбцы являются элементами списка. Чтобы узнать, какие значения begin появляются в более чем один элемент из списка, смотрите на

res[ rowSums(res>0) > 1, ] 
#  g 
# begin 1 2 3 
# 3 1 1 0 
# 14 0 1 1 

Вероятно любой дальнейший анализ вы должны сделать должно быть сделано на full, а не в списке data.frames, особенно если эффективность является проблемой.

+1

Я попробую это позже сегодня, чтобы подтвердить, что он работает. – rdevn00b

+1

Это работает довольно хорошо, спасибо! – rdevn00b

1

Простой способ свернуть элементы списка и использовать table сосчитать

# Recreate the data frame 
a <- list(
    data.frame(begin = c(3, 9, 11), end = c(5, 10, 14)), 
    data.frame(begin = c(3, 14, 19), end = c(7, 18, 24)), 
    data.frame(begin = c(6, 14, 18), end = c(9, 22, 30))) 

# "Collapse" the begin columns into a vector. 
# We use unlist in case the data frames are not all 
# of the same length(thanks @Frank for pointing this out) 
a.beg <- unlist(sapply(a, function(x){x$begin})) 

# Count the elements 
tb <- table(a.beg) 

# Get the ones repeated at least twice 
# (need to cast to numeric as names are strings) 
intersection <- as.numeric(names(tb[tb>=2])) 

> intersection 
[1] 3 14 
+0

Это не масштабируемо! – rdevn00b

+0

@ rdevn00b является масштабируемым для любого количества элементов в ... как вы хотите масштабировать? – nico

+0

@Frank хорошая точка, добавлено – nico

Смежные вопросы