我有一份清单
[[1]]
[1] 7
[[2]]
[1] 10 11 12 211 446 469
[[3]]
[1] 10 11 12 13
[[4]]
[1] 11 12 13 215
[[5]]
[1] 15 16
[[6]]
[1] 15 17 216 225
Run Code Online (Sandbox Code Playgroud)
我想合并具有公共元素的列表切片,并索引已合并列表切片的索引.我想要的输出如下.
$`1`
[1] 7
$`2`, `3`, `4`
[1] 10 11 12 13 211 215 446 469
$`5`,`6`
[1] 15 16 17 216 225
Run Code Online (Sandbox Code Playgroud)
(我将原始列表切片索引作为新列表名称,但任何形式的输出都可以.)
可重复的数据:
mylist <- list(7, c(10, 11, 12, 211, 446, 469), c(10, 11, 12, 13), c(11,
12, 13, 215), c(15, 16), c(15, 17, 216, 225))
Run Code Online (Sandbox Code Playgroud)
Ron*_*hah 10
对解决方案不满意,但我认为这给出了答案.仍有改进的余地:
unique(sapply(lst, function(x)
unique(unlist(lst[sapply(lst, function(y)
any(x %in% y))]))))
#[[1]]
#[1] 7
#[[2]]
#[1] 10 11 12 211 446 469 13 215
#[[3]]
#[1] 15 16 17 216 225
Run Code Online (Sandbox Code Playgroud)
这基本上是双循环,以检查列表元素是否存在于任何其他列表中.如果您找到任何此类元素,则将它们合并在一起,仅从中获取unique
值.
数据
lst <- list(7, c(10 ,11 ,12, 211, 446, 469), c(10, 11, 12, 13),c(11 ,12, 13 ,215),
c(15, 16), c(15, 17 ,216 ,225))
Run Code Online (Sandbox Code Playgroud)
这是使用"矩阵"和"igraph"包的另一种方法.
首先,我们需要提取哪些元素相关的信息.使用稀疏矩阵可以有助于节省大量内存使用量:
library(Matrix)
i = rep(1:length(mylist), lengths(mylist))
j = factor(unlist(mylist))
tab = sparseMatrix(i = i, j = as.integer(j), x = TRUE, dimnames = list(NULL, levels(j)))
#as.matrix(tab) ## just to print colnames
# 7 10 11 12 13 15 16 17 211 215 216 225 446 469
#[1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#[2,] FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE
#[3,] FALSE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#[4,] FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
#[5,] FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#[6,] FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE TRUE TRUE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)
查找每个元素是否相互连接:
connects = tcrossprod(tab, boolArith = TRUE)
#connects
#6 x 6 sparse Matrix of class "lsCMatrix"
#
#[1,] | . . . . .
#[2,] . | | | . .
#[3,] . | | | . .
#[4,] . | | | . .
#[5,] . . . . | |
#[6,] . . . . | |
Run Code Online (Sandbox Code Playgroud)
然后,使用图表,我们可以对"mylist"的索引进行分组:
library(igraph)
# 'graph_from_adjacency_matrix' seems to not work with the "connects" object directly.
# An alternative to coercing "connects" here would be to build it as 'tcrossprod(tab) > 0'
group = clusters(graph_from_adjacency_matrix(as(connects, "lsCMatrix")))$membership
#group
#[1] 1 2 2 2 3 3
Run Code Online (Sandbox Code Playgroud)
最后,连接:
tapply(mylist, group, function(x) sort(unique(unlist(x))))
#$`1`
#[1] 7
#
#$`2`
#[1] 10 11 12 13 211 215 446 469
#
#$`3`
#[1] 15 16 17 216 225
tapply(1:length(mylist), group, toString)
# 1 2 3
# "1" "2, 3, 4" "5, 6"
Run Code Online (Sandbox Code Playgroud)