关于计数对也提出了类似的问题,但是似乎没有一个对于我想做的事情特别有用。
我想要的是计算多个列表元素之间的对数并将其转换为矩阵。例如,如果我有一个像这样的列表:
myList <- list(
a = c(2,4,6),
b = c(1,2,3,4),
c = c(1,2,5,7),
d = c(1,2,4,5,8)
)
Run Code Online (Sandbox Code Playgroud)
我们可以看到该对出现了 3 次( 、 、和1:2中各出现一次)。该对仅在 中出现一次。该对出现 2 次(在和中各出现一次)...等等。abc1:3b1:4bd
我想计算一对出现的次数,然后将其转换为对称矩阵。例如,我想要的输出看起来像我手动创建的矩阵(其中矩阵的每个元素都是该对值的总计数):
> myMatrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 0 3 1 2 2 0 1 1
[2,] 3 0 1 3 2 1 1 1
[3,] 1 1 0 1 0 0 0 0
[4,] 2 3 1 0 0 0 0 1
[5,] 2 2 0 0 0 0 1 1
[6,] 0 1 0 0 0 0 0 0
[7,] 1 1 0 0 1 0 0 0
[8,] 1 1 0 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
任何建议都非常感激
受@akrun的回答的启发,我认为你可以使用叉积来非常快速、简单地得到这个:
out <- tcrossprod(table(stack(myList)))
diag(out) <- 0
# values
#values 1 2 3 4 5 6 7 8
# 1 0 3 1 2 2 0 1 1
# 2 3 0 1 3 2 1 1 1
# 3 1 1 0 1 0 0 0 0
# 4 2 3 1 0 1 1 0 1
# 5 2 2 0 1 0 0 1 1
# 6 0 1 0 1 0 0 0 0
# 7 1 1 0 0 1 0 0 0
# 8 1 1 0 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
原答案:
用于combn获取组合以及反转每个组合。
然后将结果转换data.frame为a。table
tab <- lapply(myList, \(x) combn(x, m=2, FUN=\(cm) rbind(cm, rev(cm)), simplify=FALSE))
tab <- data.frame(do.call(rbind, unlist(tab, rec=FALSE)))
table(tab)
# X2
#X1 1 2 3 4 5 6 7 8
# 1 0 3 1 2 2 0 1 1
# 2 3 0 1 3 2 1 1 1
# 3 1 1 0 1 0 0 0 0
# 4 2 3 1 0 1 1 0 1
# 5 2 2 0 1 0 0 1 1
# 6 0 1 0 1 0 0 0 0
# 7 1 1 0 0 1 0 0 0
# 8 1 1 0 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
我们可以循环list,获取 的成对组合combn,stack将其转换为两列数据集,将“值”列转换为factor指定levels为 1 到 8,获取频率计数 ( table),执行叉积 ( crossprod),转换输出回到逻辑,然后逐Reduce元素list相加,最后将diag所有元素赋值为 0。(如果需要,将names的属性设置dimnames为 NULL
out <- Reduce(`+`, lapply(myList, function(x)
crossprod(table(transform(stack(setNames(
combn(x,
2, simplify = FALSE), combn(x, 2, paste, collapse="_"))),
values = factor(values, levels = 1:8))[2:1]))> 0))
diag(out) <- 0
names(dimnames(out)) <- NULL
Run Code Online (Sandbox Code Playgroud)
-输出
> out
1 2 3 4 5 6 7 8
1 0 3 1 2 2 0 1 1
2 3 0 1 3 2 1 1 1
3 1 1 0 1 0 0 0 0
4 2 3 1 0 1 1 0 1
5 2 2 0 1 0 0 1 1
6 0 1 0 1 0 0 0 0
7 1 1 0 0 1 0 0 0
8 1 1 0 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)