合并两个不同大小的矩阵

时间:2015-09-25 14:11:28

标签: r matrix merge

我有两个对称相关矩阵,其中一个表示另一个的子集。我想将两个矩阵合并为长格式,以后将其用于x,y图。这是一个小例子。

library(reshape)
library(ggplot2)

dist1 <- matrix(runif(16),4,4)
dist2 <- matrix(runif(9),3,3)
rownames(dist1) <- colnames(dist1) <- paste0("A",1:4)
rownames(dist2) <- colnames(dist2) <- paste0("A",1:3)

m1 <- melt(dist1)
m2 <- melt(dist2)

final <- merge(m1,m2, by=c("X1","X2"))
ggplot(final, aes(value.x,value.y)) + geom_point()

这一切都很好。 final包含与较小矩阵m2中一样多的x1,x2对。 然而,在我的现实生活中,事情看起来有所不同:

dim(m1) # the large matrix
[1] 14845516     3
dim(m2) # the small matrix
[1] 574564    3
dim(final) # the merged product
[1] 286894    4  

怀疑final对代表m2中的对的一半多一点(差异非常接近但不等于对角线单元格的数量) m2),所以也许merge()确实找到了一个三角形。但我现在的假设是m2不是m1的子集(尽管它应该是)。所以,我的问题是:

如何检查m2 [,1:2]中的所有对是否也出现在m1 [,1:2]中?

是否有更好的选择从m1和m2创建合并的数据框,其中包含两个矩阵中包含的每个X1,X2对?最佳地,仅有唯一的对,例如,从A1,A2和A2,A1,只有一对被选中。

谢谢。

2 个答案:

答案 0 :(得分:2)

您可以使用dplyr中的library(dplyr) dim(intersect(m2[,1:2],m1[1:2])) [1] 9 2 dim(m2[,1:2]) [1] 9 2 函数检查m2 [,1:2]中的所有对是否出现在m1 [,1:2]中:

merge

另外,尝试检查您的变量是否被编码为因子。如果是这样,如果您在这些变量上合并数据框,则会得到奇怪的结果。最好将它们转换为字符。

至于合并数据框架的最佳方式,来自基准R的inner_join,以及来自dplyr的{​​{1}}和来自data.table数据包的连接都应该足够好处理那个任务。 data.table可能是最快的。

如果您只想要唯一的对,则应在执行合并之前运行unique(m1[,1:2])

答案 1 :(得分:1)

我认为这是一个更好的方法,应该推广到更大的集合,虽然没有直接测试很难说。我不确定您的X1X2变量是什么,但这应该有效。合并结果的行数应该等于m2(较小的矩阵)的行数。

我将您的第一行更改为library(reshape2),这会将代码的其余部分与这两个对象一起生成:

> m1
   Var1 Var2      value
1    A1   A1 0.50120206
2    A2   A1 0.07627305
3    A3   A1 0.73757589
4    A4   A1 0.24007736
5    A1   A2 0.93485899
6    A2   A2 0.67076761
7    A3   A2 0.92666447
8    A4   A2 0.79405152
9    A1   A3 0.33120170
10   A2   A3 0.48999764
11   A3   A3 0.86967692
12   A4   A3 0.01966199
13   A1   A4 0.03986184
14   A2   A4 0.50578328
15   A3   A4 0.30689141
16   A4   A4 0.54859405
> m2
  Var1 Var2      value
1   A1   A1 0.56995004
2   A2   A1 0.81317914
3   A3   A1 0.51047761
4   A1   A2 0.16949663
5   A2   A2 0.21790332
6   A3   A2 0.75785648
7   A1   A3 0.75591111
8   A2   A3 0.92541073
9   A3   A3 0.07877851

要合并它们,请使用 dplyr 包中的连接操作,例如

> final <- dplyr::full_join(m1, m2, by=c("Var1","Var2"))
Warning messages:
1: In outer_join_impl(x, y, by$x, by$y) :
  joining factors with different levels, coercing to character vector
2: In outer_join_impl(x, y, by$x, by$y) :
  joining factors with different levels, coercing to character vector

> final
   Var1 Var2    value.x    value.y
1    A1   A1 0.50120206 0.56995004
2    A2   A1 0.07627305 0.81317914
3    A3   A1 0.73757589 0.51047761
4    A4   A1 0.24007736         NA
5    A1   A2 0.93485899 0.16949663
6    A2   A2 0.67076761 0.21790332
7    A3   A2 0.92666447 0.75785648
8    A4   A2 0.79405152         NA
9    A1   A3 0.33120170 0.75591111
10   A2   A3 0.48999764 0.92541073
11   A3   A3 0.86967692 0.07877851
12   A4   A3 0.01966199         NA
13   A1   A4 0.03986184         NA
14   A2   A4 0.50578328         NA
15   A3   A4 0.30689141         NA
16   A4   A4 0.54859405         NA

(不要担心这里的警告。)

较小的对象m2中的行,列标签对将始终是唯一的,如果您只想要较小矩阵中的项目,则可以使用right_join(),例如:

> dplyr::right_join(m1, m2, by=c("Var1","Var2"))
  Var1 Var2    value.x    value.y
1   A1   A1 0.50120206 0.56995004
2   A2   A1 0.07627305 0.81317914
3   A3   A1 0.73757589 0.51047761
4   A1   A2 0.93485899 0.16949663
5   A2   A2 0.67076761 0.21790332
6   A3   A2 0.92666447 0.75785648
7   A1   A3 0.33120170 0.75591111
8   A2   A3 0.48999764 0.92541073
9   A3   A3 0.86967692 0.07877851
Warning messages:
1: In right_join_impl(x, y, by$x, by$y) :
  joining factors with different levels, coercing to character vector
2: In right_join_impl(x, y, by$x, by$y) :
  joining factors with different levels, coercing to character vector