我有一个向量列表...
A <- c("a", "b", "c", "d", "e")
B <- c("b", "e", "f", "g")
C <- c("c", "f", "g", "h", "i")
listofvectors <- list(A, B, C)
如何检查每个组合共有的元素数量? 因此,它将是比较的矩阵,并且具有相同的数字。这将给出代码指定的格式
output <- matrix(c(5, 2, 1, 2, 4, 2, 1, 2, 5), nrow = 3, ncol = 3)
dimnames(output) = list(c("A", "B", "C"), c("A", "B", "C"))
# A B C
#A 5 2 1
#B 2 4 2
#C 1 2 5
对于单个向量,我可以使用A[A %in% B]
,但是我的实际列表中有300多个向量,因此对每种组合进行此操作都需要一段时间。
理想情况下,我想避免使用循环。我还看到函数combn()
对于完成每个排列可能很有用。
任何帮助将不胜感激。
答案 0 :(得分:0)
我不确定我是否能100%理解,但这也许对您有用:
l <- list(A,B,C)
sl_ <- seq_along(l)
eg_ <- expand.grid(sl_, sl_)
matrix(mapply(function(x,y) length(intersect(l[[x]],l[[y]])),eg_$Var1, eg_$Var2 ),nrow=length(l))
# [,1] [,2] [,3]
# [1,] 5 2 1
# [2,] 2 4 2
# [3,] 1 2 5
尚未优化,因此,如果您遇到速度或内存问题,请告诉我。
答案 1 :(得分:0)
只要combn
不会太大,您确实可以使用choose(n, 2)
。
common_elements <- combn(listofvectors, 2,
FUN = function(x) intersect(x[[1]], x[[2]]), simplify = FALSE)
names(common_elements) <- vapply(combn(seq_along(listofvectors), 2, simplify = FALSE),
paste, collapse = "vs", FUN.VALUE = character(1))
#$`1vs2`
#[1] "b" "e"
#
#$`1vs3`
#[1] "c"
#
#$`2vs3`
#[1] "f" "g"
common_num <- lengths(common_elements)
#1vs2 1vs3 2vs3
# 2 1 2
library(Matrix)
#https://stackoverflow.com/a/51421029/1412059
fun <- function(x) {
n <- 0.5 + sqrt(0.25 + 2 * length(x)) #calculate dimension
i <- sequence(seq_len(n - 1)) #row indices
j <- rep(seq_len(n - 1), seq_len(n - 1)) + 1 # column indices
sparseMatrix(i = i, j = j, x = x, triangular = TRUE, dims = c(n, n))
}
output <- fun(common_num)
diag(output) <- lengths(listofvectors)
dimnames(output) <- rep(list(seq_along(listofvectors)), 2)
#3 x 3 sparse Matrix of class "dtCMatrix"
# 1 2 3
#1 5 2 1
#2 . 4 2
#3 . . 5
答案 2 :(得分:0)
最终与Roland的方法有些相似。
m = matrix(NA,nrow=length(listofvectors),ncol=length(listofvectors))
diag(m) = sapply(listofvectors,length)
m[lower.tri(m)] = apply(combn(1:3,2),2,function(x){length(intersect(listofvectors[[x[1]]],listofvectors[[x[2]]]))})
m[upper.tri(m)] = m[lower.tri(m)]
# [,1] [,2] [,3]
#[1,] 5 2 1
#[2,] 2 4 2
#[3,] 1 2 5