我有一个向量列表。。。
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()
可能对完成每一个置换都有用。
如有任何帮助,我们将不胜感激。
只要choose(n, 2)
不太大,就可以使用combn
。
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
我不确定我是否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
它没有优化,所以如果你有速度或内存问题,请告诉我。
最终与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