【问题标题】:Merging two matrices of different sizes合并两个不同大小的矩阵
【发布时间】:2025-12-16 09:55:01
【问题描述】:

我有两个对称的相关矩阵,其中一个代表另一个的子集。我想将两个矩阵合并为长格式,以便稍后将其用于 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 包含的 x1,x2 对与在较小的矩阵 m2 中找到的一样多。 然而,在我的现实生活示例中,情况看起来有所不同:

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 中,只有一对被选中。

谢谢。

【问题讨论】:

    标签: r matrix merge


    【解决方案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
    

    【讨论】:

    • 我使用 melt 的原始代码得到了相同的结果。这里唯一的区别是Var1Var2 中的级别排序不同。所以我认为在这里使用 dplyr 并没有真正的优势。
    【解决方案2】:

    您可以使用来自dplyrintersect() 函数检查 m2[,1:2] 中的所有对是否出现在 m1[,1:2] 中:

    library(dplyr)
    dim(intersect(m2[,1:2],m1[1:2]))
    [1] 9 2
    dim(m2[,1:2])
    [1] 9 2
    

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

    至于合并数据帧的最佳方法,来自基本 R 的merge,以及来自dplyrinner_join 和来自data.table 包的连接都应该足以处理该任务。 data.table 可能是最快的。

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

    【讨论】:

    • 我同意这有助于解决问题,因为它可以帮助您找出为什么(!)您的合并结果不符合预期。然而,使用unique(m1[, 1:2]) 并不能帮助消除重复条目,例如A1, A2A2, A1
    最近更新 更多