合并具有共同R中的一个元素的集合

时间:2017-06-09 18:42:14

标签: r merge

我有一个像这样的列表列表:

lista=list()    
lista[[1]]=c( 1,  2,  4,  6,  8,  9, 10, 11, 12, 19, 32, 34, 35, 36, 37, 38)    
lista[[2]]=c(7,8)    
lista[[3]]=c(13, 14, 16, 26, 27, 28, 29, 30, 31)    
lista[[4]]=c(20, 21, 23, 25, 27, 28, 29, 30)    
lista[[5]]=c(9,10,39)
lista[[6]]=c(39,40)

所以我想要这样的输出:

group[[1]]=c(1,2,4,6,7,8,9,10,11,12,19,32,34,35,36,37,38,39,40)    
group[[2]]=c(13,14,16,20,21,23,24,26,27,28,29,30,31)

"打开方框":

lista[[1]]lista[[2]]lista[[5]]合并,因为它们有共同元素。

lista[[5]]lista[[6]]合并,因为它们有共同元素。 因此,lista[[5]]连接lista[[1]]lista[[2]]lista[[5]]

我正在尝试这张票:

Merge lists that share common elements

2 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案:

lista=list()    
lista[[1]]=c( 1,  2,  4,  6,  8,  9, 10, 11, 12, 19, 32, 34, 35, 36, 37, 38)    
lista[[2]]=c(7,8)    
lista[[3]]=c(13, 14, 16, 26, 27, 28, 29, 30, 31)    
lista[[4]]=c(20, 21, 23, 25, 27, 28, 29, 30)    
lista[[5]]=c(9,10,39)
lista[[6]]=c(39,40)


canBeMerged <- function(x,y){
  length(intersect(x,y)) > 0
}
mergeFun <- function(x,y){
  sort(union(x,y))
}

group <- Reduce(f=function(acc,curr){
  # since we wrapped each element inside a list with Map, here we unwrap the current element
  currVec <- curr[[1]]
  # we search in the accumulated list of "unmergeable" vectors 
  # if there is one which can be merged with currVec
  toMergeIdx <- Position(f=function(x) canBeMerged(x,currVec), acc)
  if(is.na(toMergeIdx )){ 
    # none can be merged, let's simply add currVec to the accumulated list
    acc[[length(acc)+1]] <- currVec
  }else{
    # currVec can be merged with the vector at position toMergeIdx, so we merge the 
    acc[[toMergeIdx]] <- mergeFun(acc[[toMergeIdx]],currVec)
  }
  return(acc)
},Map(lista,f=list))

结果:

> group
[[1]]
 [1]  1  2  4  6  7  8  9 10 11 12 19 32 34 35 36 37 38 39 40

[[2]]
 [1] 13 14 16 20 21 23 25 26 27 28 29 30 31

说明:

Reduce使用二元函数连续组合给定向量的元素,例如给定元素c(1,3,7)的向量和二元函数+ Reduce(c(1,3,7),f='+')将调用函数一次执行1+3(Reduce的初始累积值是第一个值,如果不是指定),然后再次调用该函数传递当前累计值4并将其与下一个值相加,计算4+7,然后最终返回11

因此,在这种情况下,我们希望使用Reduce迭代向量列表并迭代组合它们,如果它们可以合并或保留它们,如果不是。 因此,在这种情况下,Reduce的累积值将是&#34; unmergeable&#34;向量,要检查并最终合并到下一个向量。

请注意,由于Reduce的累计值和下一个值必须属于同一类型,因此我们需要使用listaMap的每个元素包装在一个列表中。

答案 1 :(得分:0)

这是另一种方法,它构造一个矩阵,显示列表中哪些元素相互交叉,并使用igraph包推导出这些组:

library(igraph)
## Construct the matrix
m = sapply(lista,function(x) sapply(lista,function(y) length(intersect(x,y))>0))
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,]  TRUE  TRUE FALSE FALSE  TRUE FALSE
[2,]  TRUE  TRUE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE  TRUE  TRUE FALSE FALSE
[4,] FALSE FALSE  TRUE  TRUE FALSE FALSE
[5,]  TRUE FALSE FALSE FALSE  TRUE  TRUE
[6,] FALSE FALSE FALSE FALSE  TRUE  TRUE

## Determine the groups of the graph constructed from m
groups = groups(components(graph_from_adjacency_matrix(m)))
$`1`
[1] 1 2 5 6

$`2`
[1] 3 4

## Get the unique elements of each group
res = lapply(groups,function(x) sort(unique(unlist(lista[x]))))
$`1`
 [1]  1  2  4  6  7  8  9 10 11 12 19 32 34 35 36 37 38 39 40

$`2`
 [1] 13 14 16 20 21 23 25 26 27 28 29 30 31