填充 R 中距离矩阵中缺失的 rows/columns
Filling in missing rows/columns in distance matrices in R
我有两个距离矩阵..但是它们中的任何一个都可能缺少项目,并且它们可能是乱序的——例如:
矩阵 #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
解决此问题的最佳方法是什么?我应该对两个矩阵进行排序然后填充缺失的 columns/rows 这样我就可以只使用 abs(m1-m2),或者有没有办法使用 row/column 标题让它们自动 "match up" 什么时候减去?
这些矩阵大约为 5000x5000,我将有大约 1000 个矩阵可以进行成对比较,所以我宁愿对数据进行预处理,如果这会使每个计算速度显着加快。
欢迎任何提示或建议。我通常是一名 non-R 程序员,所以我通常会提出的迭代解决方案将永远持续下去——我希望 "R way" 做事的速度会明显加快。
我们创建一个名称索引 ('Un1'),它是第一个 ('m1') 和第二个 ('m2') matrix
名称的 union
].两个新的 0 矩阵('m1N'、'm2N')是通过指定维度和基于 'Un1' 的 dim 名称创建的。通过 row/column 索引,我们将这些矩阵中的 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
中的值。使用 lapply
遍历 list
获取列名,使用 union
作为 f
in Reduce
,sort
获取 unique
元素.
lst <- mget(ls(pattern='m\d+')) #change the pattern accordingly
Un1 <- sort(Reduce(union, lapply(lst, colnames)))
我们可以创建另一个 matrix
为 0 的 list
。
lst1 <- lapply(seq_along(lst), function(i)
matrix(0, ncol=length(Un1), nrow=length(Un1), dimnames=list(Un1, Un1)))
我们可以使用'lst'的对应矩阵的row/column索引改变'lst1'的对应元素使用Map
.
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='_')
另一种使用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
我有两个距离矩阵..但是它们中的任何一个都可能缺少项目,并且它们可能是乱序的——例如:
矩阵 #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
解决此问题的最佳方法是什么?我应该对两个矩阵进行排序然后填充缺失的 columns/rows 这样我就可以只使用 abs(m1-m2),或者有没有办法使用 row/column 标题让它们自动 "match up" 什么时候减去?
这些矩阵大约为 5000x5000,我将有大约 1000 个矩阵可以进行成对比较,所以我宁愿对数据进行预处理,如果这会使每个计算速度显着加快。
欢迎任何提示或建议。我通常是一名 non-R 程序员,所以我通常会提出的迭代解决方案将永远持续下去——我希望 "R way" 做事的速度会明显加快。
我们创建一个名称索引 ('Un1'),它是第一个 ('m1') 和第二个 ('m2') matrix
名称的 union
].两个新的 0 矩阵('m1N'、'm2N')是通过指定维度和基于 'Un1' 的 dim 名称创建的。通过 row/column 索引,我们将这些矩阵中的 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
中的值。使用 lapply
遍历 list
获取列名,使用 union
作为 f
in Reduce
,sort
获取 unique
元素.
lst <- mget(ls(pattern='m\d+')) #change the pattern accordingly
Un1 <- sort(Reduce(union, lapply(lst, colnames)))
我们可以创建另一个 matrix
为 0 的 list
。
lst1 <- lapply(seq_along(lst), function(i)
matrix(0, ncol=length(Un1), nrow=length(Un1), dimnames=list(Un1, Un1)))
我们可以使用'lst'的对应矩阵的row/column索引改变'lst1'的对应元素使用Map
.
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='_')
另一种使用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