如何根据另一个类似(但不等同)的矩阵对矩阵的行进行排序?

huangapple go评论72阅读模式
英文:

How to sort a matrix`s row based on another similar (not equivalent) matrix?

问题

You can achieve this in R by using the following code to reorder matrix B based on the order of matrix A:

# Create an order vector based on the first column of A
order_vector <- order(A[, 1])

# Reorder matrix B based on the order vector
B_reordered <- B[order_vector, ]

# Print the reordered matrix B
B_reordered

This code first calculates an order vector based on the first column of matrix A, which determines the desired order of rows in matrix B. Then, it reorders matrix B according to this order vector, resulting in the reordered matrix B_reordered.

英文:

I have two matrices with equal dimension in R. First columns are same. And they elements are such that they have same element but their position according to row and column are different. I am stating my problem with my code below:

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)

This is the output:

&gt; 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

and

&gt; 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

You can see the first columns are exactly similar, and last rows are too. The elements of the other rows are similar too but they are in different columns. Also corresponding rows do not contain similar elements.

Now, I want to sort the second matrix B according to A, that is the elements do not change their position based on columns, but just the row will be changed.

As for example, A[3,] and B[5,] contain same elements. I want B[5,] to be in the B[3,] position.

How can I do this?

答案1

得分: 1

我可以帮您翻译这段代码的注释部分,以下是翻译结果:

"我相信有更高效的方法来解决您的问题,但一种方法是将 A 的每一行与 B 的每一行进行比较,为了做到这一点,我们使用了嵌套的 apply

在较低的 apply 循环内,我们使用一些逻辑 y[all(sort(y) == sort(x))],它在对它们进行排序后进行比较。

apply(A, 1, \(x) {
  apply(B, 1, \(y){
    y[all(sort(y) == sort(x))]
  })
}) |&gt; 
  unlist() |&gt; 
  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

"

英文:

I'm sure there are more efficient ways to solve your problem but one way to do so is by comparing every row of A with every row of B, to do that we use nested apply

within the lower apply loop we use some logic y[all(sort(y) == sort(x))]
which compares them after sorting them both

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

If you have an older version of R ( < 4.1) without base piping, then you can run the code above like this:

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

This results in:

     [,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

答案2

得分: 1

以下是您提供的代码的翻译部分:

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

## 匹配排序后的行,找到每行在A中的位置
## 然后根据该位置重新排列B 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
## 用于确保列顺序相同的抽查检查
B_sorted[3,] == B[5,]
#> [1] TRUE TRUE TRUE TRUE TRUE
B_sorted[2,] == B[9,]
#> [1] TRUE TRUE TRUE TRUE TRUE

## 检查排序后的B和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)
英文:

This answer is based on this thread: https://stackoverflow.com/questions/64518369/rhow-would-i-match-the-rows-of-one-matrix-to-the-rows-in-another-matrix-regar

a &lt;- t(apply(A,1,sort))
b &lt;- 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))),] -&gt; B_sorted

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

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

<sup>Created on 2023-05-22 with reprex v2.0.2</sup>

Data:

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)

huangapple
  • 本文由 发表于 2023年5月22日 07:26:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76302317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定