【问题标题】:Filling in missing rows/columns in distance matrices in R在R中的距离矩阵中填充缺失的行/列
【发布时间】:2015-12-11 03:32:32
【问题描述】:

我有两个距离矩阵.. 但它们中的任何一个都可能缺少项目,并且它们可能是乱序的——例如:

矩阵 #1(缺少项目 c)

  a b d 
a 0 2 3 
b 2 0 4 
d 3 4 0 

矩阵 #2(缺少项目 b,并且项目乱序)

  d c a
d 0 1 2 
c 1 0 1 
a 2 1 0 

我想找出矩阵之间的差异,同时假设任何缺失的项目都是 0。所以,我得到的矩阵应该是:

  a b c d
a 0 2 1 1
b 2 0 0 4
c 1 0 0 1
d 1 4 1 0

解决此问题的最佳方法是什么?我应该对两个矩阵进行排序,然后填充缺失的列/行,这样我就可以只使用 abs(m1-m2),还是有办法使用行/列标题让它们在减去时自动“匹配”?

这些矩阵大约为 5000x5000,我将有大约 1000 个矩阵来进行成对比较,所以我宁愿对数据进行预处理,如果这样可以显着加快每次计算。

欢迎任何提示或建议。我通常是一个非 R 程序员,所以我通常会提出一个迭代解决方案需要很长时间——我希望用“R 方式”做事会明显更快。

【问题讨论】:

    标签: r matrix distance


    【解决方案1】:

    我们创建一个名称索引 ('Un1'),它是第一个 ('m1') 和第二个 ('m2') matrix 的名称的 union。通过基于 'Un1' 指定尺寸和暗淡名称来创建两个新的 0 矩阵('m1N'、'm2N')。通过行/列索引,我们将这些矩阵中的0值改为'm1'、'm2'中的值,相减得到绝对值。

    Un1 <- sort(union(colnames(m1), colnames(m2)))
    m1N <- matrix(0, ncol=length(Un1), nrow=length(Un1), dimnames=list(Un1, Un1))
    m2N <- m1N
    m1N[rownames(m1), colnames(m1)] <- m1
    m2N[rownames(m2), colnames(m2)] <- m2
    abs(m1N-m2N)
    #  a b c d
    #a 0 2 1 1
    #b 2 0 0 4
    #c 1 0 0 1
    #d 1 4 1 0
    

    更新

    如果我们有多个对象名称为m 后跟数字的矩阵,我们可以将它们放在list 中。我们使用ls 获取对象名称,使用mget 获取list 中的值。循环遍历listlapply 以获取列名,在Reducesort 中使用union 作为f 以获取unique 元素。

    lst <- mget(ls(pattern='m\\d+')) #change the pattern accordingly
    Un1 <- sort(Reduce(union, lapply(lst, colnames)))
    

    我们可以创建另一个listmatrix 为 0。

    lst1 <- lapply(seq_along(lst), function(i) 
        matrix(0, ncol=length(Un1), nrow=length(Un1), dimnames=list(Un1, Un1)))
    

    我们可以使用Map使用'lst'对应矩阵的行/列索引来改变'lst1'的对应元素。

    lst2 <- Map(function(x,y) {x[rownames(y), colnames(y)] <- y; x}, lst1, lst)
    

    如果我们需要成对差异,combn 可能是一个选项

    lst3 <- combn(seq_along(lst2),2, FUN=function(x) 
                          list(abs(lst2[[x[1]]]-lst2[[x[2]]])))
    names(lst3) <- combn(seq_along(lst2), 2, FUN=paste, collapse='_')
    

    【讨论】:

    • 谢谢,完美!一个后续问题——如果我有一个很大的矩阵向量,我如何才能在不遍历该向量的情况下成为所有列名的联合的第一步?
    • @Stan 更新了帖子。但是,当有更多 2 个矩阵时,我不确定你想如何获得差异。
    • 谢谢!我将创建一个矩阵的距离矩阵——即找出每对矩阵之间的差异并创建一个矩阵距离图。所以,你对 combn 的建议是完美的!
    【解决方案2】:

    使用match的另一种方法(开头类似于@akrun):

    func = function(cols, m)
    {
        res = `dimnames<-`(m[match(cols,rownames(m)), match(cols,colnames(m))],
                           list(cols, cols))
        ifelse(is.na(res), 0, res)
    }
    
    
    cols = sort(union(colnames(m1), colnames(m2)))
    abs(func(cols,m1) - func(cols,m2))
    #  a b c d
    #a 0 2 1 1
    #b 2 0 0 4
    #c 1 0 0 1
    #d 1 4 1 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-12
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多