我有一个像这样的列表列表:
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]]
。
我正在尝试这张票:
答案 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的累计值和下一个值必须属于同一类型,因此我们需要使用lista
将Map
的每个元素包装在一个列表中。
答案 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