【问题标题】:How to add to dist object如何添加到 dist 对象
【发布时间】:2014-09-11 13:27:12
【问题描述】:

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

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

【问题讨论】:

    标签: r add distance


    【解决方案1】:

    所以我假设你想在进行算术之前匹配距离矩阵之间的暗名。据我所知,使用常规矩阵没有简单的方法可以做到这一点,这意味着让它适用于距离矩阵的可能性更小。一种策略是使用名称扩展距离矩阵值,进行合并和聚合,然后转换回距离矩阵。我创建了一些辅助函数来简化此操作。首先,这是一种将对角距离矩阵转换为数据帧中成对距离的方法

    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
    

    因此,需要做一些工作来转换对象以匹配标签,但这很简单。

    【讨论】:

    • 我已经测试了代码,因为默认的距离矩阵是一个下三角矩阵,也许在 as.data.frame.dist 函数中,d1 和 d2 应该这样编辑:id1 = unlist (sapply(1:(length(n)-1), function(i) rep(n[i],length(n)-i))); id2 = unlist(sapply(2:length(n), function(i) n[i:length(n)])),
    猜你喜欢
    • 2014-09-14
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 2012-01-09
    • 2017-05-03
    • 1970-01-01
    • 2014-08-31
    相关资源
    最近更新 更多