我有两个距离矩阵..但是他们中的任何一个都可能缺少物品,而且它们可能会出现故障 - 例如:
矩阵#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方式"做得快得多的事情。
答案 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
中的值。使用list
与lapply
循环以获取列名称,在union
,f
中使用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