在R中工作,try 根据组(列)中的共享成员身份计算数据框(每行是一个项目)中的行之间的相似性/距离.然而,我不希望零值(即不是组中的成员)导致相似性.(我想要的有点像曼哈顿距离,但有不同的处理0‘S).
例如,对于此数据集:
Group1 | Group2 | Group3 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 1 |
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
我想要一个类似如下的相似性矩阵:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
0 | 1 | 1 | 0 | 2 | 1 | 1 | 2 |
0 | 1 | 0 | 1 | 1 | 2 | 1 | 2 |
0 | 0 | 1 | 1 | 1 | 1 | 2 | 2 |
0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 |
请注意,对角线值对于我的下游应用程序并不是特别重要,所以给出与此相同但对角线不同的输出的替代方法对我来说是一个很好的解决方案.
给定第一个矩阵,可以计算第二个相似性矩阵的一些非常非常慢的代码如下:
calc_simil <- function(x) {
out <- matrix(nrow = nrow(x), ncol = nrow(x))
combos <- expand.grid(1:nrow(x), 1:nrow(x))
for (myrow in 1:nrow(combos)) {
temp <- x[c(combos[myrow, 1], combos[myrow, 2]), ]
out[combos[myrow, 1], combos[myrow, 2]] <-
out[combos[myrow, 2], combos[myrow, 1]] <-
sum((1-apply(temp, function(x) {any(x == 0)}, MARGIN = 2)) *
(1 - abs(temp[1, ] - temp[2, ])))
}
return(out)
}
我知道一定有一种更有效的方法来做这件事,可能是使用一些矩阵乘法魔法,但我想不出来.我还研究了各种计算距离的内置方法,包括R包中的一些函数,但似乎没有一个方法计算共享群的数量,而忽略共享群的缺席.
有谁有什么建议吗?我是不是简单地忽略了一个常见的内置距离方法?或者,有没有更快的方法来计算这种距离/相似性?