R语言 如何根据另一个类似(不等价)的矩阵对矩阵的行进行排序?

dgtucam1  于 2023-05-26  发布在  其他
关注(0)|答案(2)|浏览(169)

我有两个在R中维数相等的矩阵。第一列相同。这些元素是这样的,它们具有相同的元素,但它们的位置根据行和列是不同的。我在下面说明我的代码的问题:

A =matrix(c(1,  0,    0 ,   0 ,   0, 1,    0    ,0 ,   0  ,  2,     1  ,  0    ,0   , 0  ,  3,     1   , 0   , 0,    0 ,   4,     1   , 0  ,  0 ,   0,    5,     1,    0 ,   0  ,  2   , 3,     1,    0,    0   , 2  ,  4,     1,    0   , 0    ,2 ,   5,     1,    0  ,  0    ,3,    4,    1 ,   0  ,  0,    3  ,  5,    1 ,   0 ,   0 ,   4 ,   5,    1 ,   0    ,2  ,  3,    4,    1 ,   0   , 2   , 3   , 5,    1 ,   0  ,  2    ,4  ,  5,    1 ,   0 ,   3   , 4 ,   5,    1  ,  2,    3    ,4,    5), nrow=16, byrow=TRUE)

B =matrix(c(1 ,   0    ,0,    0   , 0, 1,    0   , 0,    0 ,   5,    1,    0   , 0,    4 ,   0,     1 ,   0 ,   0 ,   4  ,  5,    1  ,  0 ,   3   , 0  ,  0,     1  ,  0   , 3,    0  ,  5,     1   , 0  ,  3 ,   4 ,   0,     1    ,0 ,   3  ,  4,    5,     1  ,  2,    0   , 0  ,  0,    1   , 2  ,  0,    0  ,  5,    1,    2 ,   0 ,   4 ,   0,    1 ,   2    ,0  ,  4    ,5,    1  ,  2   , 3   , 0   , 0,    1   , 2  ,  3    ,0  ,  5,    1   , 2 ,   3    ,4 ,   0,    1    ,2,    3    ,4,    5), nrow=16, byrow=TRUE)

这是输出:

> A
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    0    0    0    0
 [2,]    1    0    0    0    2
 [3,]    1    0    0    0    3
 [4,]    1    0    0    0    4
 [5,]    1    0    0    0    5
 [6,]    1    0    0    2    3
 [7,]    1    0    0    2    4
 [8,]    1    0    0    2    5
 [9,]    1    0    0    3    4
[10,]    1    0    0    3    5
[11,]    1    0    0    4    5
[12,]    1    0    2    3    4
[13,]    1    0    2    3    5
[14,]    1    0    2    4    5
[15,]    1    0    3    4    5
[16,]    1    2    3    4    5

> B
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    0    0    0    0
 [2,]    1    0    0    0    5
 [3,]    1    0    0    4    0
 [4,]    1    0    0    4    5
 [5,]    1    0    3    0    0
 [6,]    1    0    3    0    5
 [7,]    1    0    3    4    0
 [8,]    1    0    3    4    5
 [9,]    1    2    0    0    0
[10,]    1    2    0    0    5
[11,]    1    2    0    4    0
[12,]    1    2    0    4    5
[13,]    1    2    3    0    0
[14,]    1    2    3    0    5
[15,]    1    2    3    4    0
[16,]    1    2    3    4    5

你可以看到第一列是完全相似的,最后一行也是。其他行的元素也是类似的,但是它们在不同的列中。相应的行也不包含类似的元素。
现在,我想根据A对第二个矩阵B进行排序,也就是说,元素不会根据列改变它们的位置,但只有行会改变。
例如,A[3,]B[5,]包含相同的元素。我希望B[5,]位于B[3,]位置。
我该怎么做?

au9on6nz

au9on6nz1#

这个答案是基于这个线程:R::How would I match the rows of one matrix to the rows in another matrix, regardless of the column order?

a <- t(apply(A,1,sort))
b <- t(apply(B,1,sort))

## match the sorted rows to find the position of each row in A
## then rearrange B based on that B[row_order, ]
B[match(do.call(paste, as.data.frame(a)), do.call(paste, as.data.frame(b))),] -> B_sorted

#>       [,1] [,2] [,3] [,4] [,5]
#>  [1,]    1    0    0    0    0
#>  [2,]    1    2    0    0    0
#>  [3,]    1    0    3    0    0
#>  [4,]    1    0    0    4    0
#>  [5,]    1    0    0    0    5
#>  [6,]    1    2    3    0    0
#>  [7,]    1    2    0    4    0
#>  [8,]    1    2    0    0    5
#>  [9,]    1    0    3    4    0
#> [10,]    1    0    3    0    5
#> [11,]    1    0    0    4    5
#> [12,]    1    2    3    4    0
#> [13,]    1    2    3    0    5
#> [14,]    1    2    0    4    5
#> [15,]    1    0    3    4    5
#> [16,]    1    2    3    4    5
## Spot Check to make sure the column orders are the same 
B_sorted[3,] == B[5,]
#> [1] TRUE TRUE TRUE TRUE TRUE
B_sorted[2,] == B[9,]
#> [1] TRUE TRUE TRUE TRUE TRUE

## check the rowSums between sorted B and A
all(rowSums(B_sorted) == rowSums(A))
#> [1] TRUE

创建于2023-05-22带有reprex v2.0.2

数据:
A =matrix(c(1,  0,    0 ,   0 ,   0, 1,    0    ,0 ,   0  ,  2,     1  ,  0    ,0   , 0  ,  3,     1   , 0   , 0,    0 ,   4,     1   , 0  ,  0 ,   0,    5,     1,    0 ,   0  ,  2   , 3,     1,    0,    0   , 2  ,  4,     1,    0   , 0    ,2 ,   5,     1,    0  ,  0    ,3,    4,    1 ,   0  ,  0,    3  ,  5,    1 ,   0 ,   0 ,   4 ,   5,    1 ,   0    ,2  ,  3,    4,    1 ,   0   , 2   , 3   , 5,    1 ,   0  ,  2    ,4  ,  5,    1 ,   0 ,   3   , 4 ,   5,    1  ,  2,    3    ,4,    5), nrow=16, byrow=TRUE)

B =matrix(c(1 ,   0    ,0,    0   , 0, 1,    0   , 0,    0 ,   5,    1,    0   , 0,    4 ,   0,     1 ,   0 ,   0 ,   4  ,  5,    1  ,  0 ,   3   , 0  ,  0,     1  ,  0   , 3,    0  ,  5,     1   , 0  ,  3 ,   4 ,   0,     1    ,0 ,   3  ,  4,    5,     1  ,  2,    0   , 0  ,  0,    1   , 2  ,  0,    0  ,  5,    1,    2 ,   0 ,   4 ,   0,    1 ,   2    ,0  ,  4    ,5,    1  ,  2   , 3   , 0   , 0,    1   , 2  ,  3    ,0  ,  5,    1   , 2 ,   3    ,4 ,   0,    1    ,2,    3    ,4,    5), nrow=16, byrow=TRUE)
cigdeys3

cigdeys32#

我相信有更有效的方法来解决您的问题,但其中一种方法是将A的每一行与B的每一行进行比较,为此我们使用嵌套的apply
在较低的apply循环中,我们使用一些逻辑y[all(sort(y) == sort(x))],它在对它们进行排序后比较它们

apply(A, 1, \(x) {
  apply(B, 1, \(y){
    y[all(sort(y) == sort(x))]
  })
}) |> 
  unlist() |> 
  matrix(ncol  = ncol(A), byrow = T)

如果你有一个旧版本的R(< 4.1),没有基础管道,那么你可以像这样运行上面的代码:

matrix(
unlist(
  apply(A, 1, function(x) {
    apply(B, 1, function(y){
      y[all(sort(y) == sort(x))]
    })
  })
  ), 
ncol  = ncol(A), byrow = T)

这导致:

[,1] [,2] [,3] [,4] [,5]
 [1,]    1    0    0    0    0
 [2,]    1    2    0    0    0
 [3,]    1    0    3    0    0
 [4,]    1    0    0    4    0
 [5,]    1    0    0    0    5
 [6,]    1    2    3    0    0
 [7,]    1    2    0    4    0
 [8,]    1    2    0    0    5
 [9,]    1    0    3    4    0
[10,]    1    0    3    0    5
[11,]    1    0    0    4    5
[12,]    1    2    3    4    0
[13,]    1    2    3    0    5
[14,]    1    2    0    4    5
[15,]    1    0    3    4    5
[16,]    1    2    3    4    5

相关问题