在R中填充距离矩阵中缺少的行/列

时间:2015-09-15 01:59:49

标签: r matrix distance

我有两个距离矩阵..但是他们中的任何一个都可能缺少物品,而且它们可能会出现故障 - 例如:

矩阵#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),或者是否有办法使用行/列标题自动生成它们#34;匹配&#34 ;什么时候减去?

这些矩阵大约是5000x5000,并且我将有大约1000个进行成对比较,所以我更喜欢预处理数据,如果这样可以使每次计算明显加快。 / p>

欢迎任何提示或建议。我通常是非R程序员,所以我通常会提出的迭代解决方案将永远存在 - 我希望通过" R方式"做得快得多的事情。

2 个答案:

答案 0 :(得分:2)

我们创建一个名称索引('Un1'),它是第一个('m1')和第二个('m2')union名称的matrix。通过基于'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获取对象名称,使用list获取mget中的值。使用listlapply循环以获取列名称,在unionf中使用Reduce作为sort获取{{1}元素。

unique

我们可以创建另一个lst <- mget(ls(pattern='m\\d+')) #change the pattern accordingly Un1 <- sort(Reduce(union, lapply(lst, colnames))) list为0。

matrix

我们可以使用lst1 <- lapply(seq_along(lst), function(i) matrix(0, ncol=length(Un1), nrow=length(Un1), dimnames=list(Un1, Un1))) 使用'lst'的相应矩阵的行/列索引来更改'lst1'的相应元素。

Map

如果我们需要成对差异,lst2 <- Map(function(x,y) {x[rownames(y), colnames(y)] <- y; x}, lst1, lst) 可能是一个选项

combn

答案 1 :(得分: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