给定矩阵
structure(list(X1 = c(1L, 2L, 3L, 4L, 2L, 5L), X2 = c(2L, 3L,
4L, 5L, 3L, 6L), X3 = c(3L, 4L, 4L, 5L, 3L, 2L), X4 = c(2L, 4L,
6L, 5L, 3L, 8L), X5 = c(1L, 3L, 2L, 4L, 6L, 4L)), .Names = c("X1",
"X2", "X3", "X4", "X5"), class = "data.frame", row.names = c(NA,
-6L))
我想创建一个5 x 5距离矩阵,其中匹配比率和所有列之间的总行数。例如,X4和X3之间的距离应该是0.5,因为两列都匹配6次中的3次。
我尝试使用“proxy”包中的dist(test, method="simple matching")
,但此方法仅适用于二进制数据。
答案 0 :(得分:6)
使用outer
(再次: - )
my.dist <- function(x) {
n <- nrow(x)
d <- outer(seq.int(ncol(x)), seq.int(ncol(x)),
Vectorize(function(i,j)sum(x[[i]] == x[[j]]) / n))
rownames(d) <- names(x)
colnames(d) <- names(x)
return(d)
}
my.dist(x)
# X1 X2 X3 X4 X5
# X1 1.0000000 0.0000000 0.0 0.0 0.3333333
# X2 0.0000000 1.0000000 0.5 0.5 0.1666667
# X3 0.0000000 0.5000000 1.0 0.5 0.0000000
# X4 0.0000000 0.5000000 0.5 1.0 0.0000000
# X5 0.3333333 0.1666667 0.0 0.0 1.0000000
答案 1 :(得分:2)
这是一个镜头(dt是你的矩阵):
library(reshape)
df = expand.grid(names(dt),names(dt))
df$val=apply(df,1,function(x) mean(dt[x[1]]==dt[x[2]]))
cast(df,Var2~Var1)
答案 2 :(得分:2)
这是一个比其他两个更快的解决方案,虽然有点难看。我假设速度颠簸来自不使用mean()
,因为它与sum()
相比可能很慢,并且还只计算输出矩阵的一半然后手动填充下三角。该函数目前在对角线上留下NA
,但您可以轻松地将其设置为1以与其他答案完全匹配diag(out) <- 1
FUN <- function(m) {
#compute all the combinations of columns pairs
combos <- t(combn(ncol(m),2))
#compute the similarity index based on the criteria defined
sim <- apply(combos, 1, function(x) sum(m[, x[1]] - m[, x[2]] == 0) / nrow(m))
combos <- cbind(combos, sim)
#dimensions of output matrix
out <- matrix(NA, ncol = ncol(m), nrow = ncol(m))
for (i in 1:nrow(combos)){
#upper tri
out[combos[i, 1], combos[i, 2]] <- combos[i,3]
#lower tri
out[combos[i, 2], combos[i, 1]] <- combos[i,3]
}
return(out)
}
我接受了另外两个答案,将它们变成了函数,并做了一些基准测试:
library(rbenchmark)
benchmark(chase(m), flodel(m), blindJessie(m),
replications = 1000,
order = "elapsed",
columns = c("test", "elapsed", "relative"))
#-----
test elapsed relative
1 chase(m) 1.217 1.000000
2 flodel(m) 1.306 1.073131
3 blindJessie(m) 17.691 14.548520
答案 3 :(得分:1)
谢谢大家的建议。根据您的答案,我详细阐述了一个三行解决方案(“test”是数据集的名称)。
require(proxy)
ff <- function(x,y) sum(x == y) / NROW(x)
dist(t(test), ff, upper=TRUE)
输出:
X1 X2 X3 X4 X5
X1 0.0000000 0.0000000 0.0000000 0.3333333
X2 0.0000000 0.5000000 0.5000000 0.1666667
X3 0.0000000 0.5000000 0.5000000 0.0000000
X4 0.0000000 0.5000000 0.5000000 0.0000000
X5 0.3333333 0.1666667 0.0000000 0.0000000
答案 4 :(得分:0)
我得到的答案如下: 第一,我对行数据进行了一些修改:
X1 = c(1L, 2L, 3L, 4L, 2L, 5L)
X2 = c(2L, 3L, 4L, 5L, 3L, 6L)
X3 = c(3L, 4L, 4L, 5L, 3L, 2L)
X4 = c(2L, 4L, 6L, 5L, 3L, 8L)
X5 = c(1L, 3L, 2L, 4L, 6L, 4L)
matrix_cor=rbind(x1,x2,x3,x4,x5)
matrix_cor
[,1] [,2] [,3] [,4] [,5] [,6]
X1 1 2 3 4 2 5
X2 2 3 4 5 3 6
X3 3 4 4 5 3 2
X4 2 4 6 5 3 8
X5 1 3 2 4 6 4
然后:
dist(matrix_cor)
X1 X2 X3 X4
X2 2.449490
X3 4.472136 4.242641
X4 5.000000 3.000000 6.403124
X5 4.358899 4.358899 4.795832 6.633250