如何添加到dist对象

时间:2014-09-11 13:27:12

标签: r add distance

示例代码如下所示,我想创建一个新对象d3=(d1+d2)/2,但您知道d1的项目与d2的项目不同,所以直接使用添加是不可能的。有什么办法?

library(recommenderlab)
data(MSWeb)
d1 = dissimilarity(MSWeb[1:5,], method = "jaccard")
d2 = dissimilarity(MSWeb[2:6,], method = "jaccard")

1 个答案:

答案 0 :(得分:1)

所以我假设你想在算术之前匹配距离矩阵之间的dimnames。据我所知,使用常规矩阵没有简单的方法,这意味着它对距离矩阵起作用的可能性更小。一种策略是用名称扩展距离矩阵值,进行合并和聚合,然后转换回距离矩阵。我已经创建了一些辅助函数来使这更容易。首先,这是一种将对角线距离矩阵转换为data.frame

中的成对距离的方法
as.data.frame.dist<-function(x) {
    stopifnot(is(x, "dist"))
    s <- attr(x, "Size")
    n <- attr(x, "Labels")
    data.frame(
      id1 = unlist(sapply(1:(length(n)-1), function(i) n[1:i])),
      id2 = rep(n[-1], 1:(length(n)-1)),
      dist = as.numeric(x)
    )
}

例如,如果我们运行

as.data.frame(d1)

#    id1 id2      dist
# 1    1   2 0.7500000
# 2    1   3 0.8000000
# 3    2   3 1.0000000
# 4    1   4 1.0000000
# 5    2   4 0.3333333
# 6    3   4 1.0000000
# 7    1   5 1.0000000
# 8    2   5 1.0000000
# 9    3   5 1.0000000
# 10   4   5 1.0000000

我们将所有成对比较扩展为具有ID值的行,我们可以将其匹配到其他可能不匹配的集合。您似乎只想获取每组点的平均距离,因此您可以执行类似这样的操作

dd <- rbind(as.data.frame(d1), as.data.frame(d2))
dd <- aggregate(dist~id1+id2, dd, mean)

现在,我们想将这个data.frame转回一个距离对象,我们需要编写另一个辅助函数。这是一次这样的功能

df2dist<-function(x, ids=1:2, vals=3, lvls=NULL) {
    if(is.null(lvls)) {
        lvls <- sort(unique(c(as.character(x[,ids[1]]), as.character(x[,ids[2]]))))
    }
    i <- as.numeric(factor(x[,ids[1]], levels=lvls))
    j <- as.numeric(factor(x[,ids[2]], levels=lvls))
    stopifnot(all(i<j))
    n <- length(lvls)
    idx <- n*(i-1) - i*(i-1)/2 + j-i
    r <- rep(NA, n*(n-1)/2)
    r[idx] <- x[,vals]
    structure(r, class="dist", Labels=lvls, Size=n, Diag=FALSE, Upper=FALSE)
}

我们期望三列data.frame具有值对和它们之间的距离。我们可以在我们的样本上使用它来获取

df2dist(dd)

#           1         2         3         4         5
# 2 0.7500000                                        
# 3 0.8000000 0.6666667                              
# 4 1.0000000 0.6666667 1.0000000                    
# 5 1.0000000 0.8333333 1.0000000 1.0000000          
# 6        NA 0.3333333 1.0000000 1.0000000 1.0000000

所以有一些工作要转换对象以匹配标签,但它非常简单。