在 R 中的两个矩阵之间切换行

Switch rows between two matrices in R

设矩阵A和B。

A=c(1:5)*matrix(1,5,5)
B=10*A

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

> B
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]   20   20   20   20   20
[3,]   30   30   30   30   30
[4,]   40   40   40   40   40
[5,]   50   50   50   50   50

例如,我想在矩阵A和B之间切换第一行,即

> A
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

> B
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]   20   20   20   20   20
[3,]   30   30   30   30   30
[4,]   40   40   40   40   40
[5,]   50   50   50   50   50

使用函数,不使用任何中间向量或 for 循环。

replace 似乎没有任何中间件就可以工作

replace(A, cbind(1, 1:ncol(A)), B[1,])
replace(B, cbind(1, 1:ncol(A)), A[1,])

请注意,一旦我们对原始对象进行赋值,第二次赋值是不可能的,因为原始对象已更改


一种干净的交换方法是创建一个临时对象,rm

tmp <- A[1,]
A[1, ] <- B[1, ]
B[1, ] <- tmp
rm(tmp)
gc()

或者可能创建一个函数,在函数内部进行交换,这样一旦退出函数就会删除激活记录(因为这些是按值传递的)

f1 <- function(a, b) {
       t1 <- a[1,]
       a[1,] <- b[1,]
       b[1,] <- t1
       return(list(a, b))
    }
list2env(setNames(f1(A, B), c('A', 'B')), .GlobalEnv)

更新

根据您在评论中的更新,您可以试试

lapply(
  1:nrow(B),
  function(k) {
    setNames(
      Map(
        function(x, ind,r) {
          x[ind, ] <- r
          x
        },
        list(A, B),
        list(1,k),
        list(B[k, ], A[1, ])
      ), c("A", "B")
    )
  }
)

这给出了

[[1]]
[[1]]$A
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

[[1]]$B
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]   20   20   20   20   20
[3,]   30   30   30   30   30
[4,]   40   40   40   40   40
[5,]   50   50   50   50   50


[[2]]
[[2]]$A
     [,1] [,2] [,3] [,4] [,5]
[1,]   20   20   20   20   20
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

[[2]]$B
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]    1    1    1    1    1
[3,]   30   30   30   30   30
[4,]   40   40   40   40   40
[5,]   50   50   50   50   50


[[3]]
[[3]]$A
     [,1] [,2] [,3] [,4] [,5]
[1,]   30   30   30   30   30
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

[[3]]$B
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]   20   20   20   20   20
[3,]    1    1    1    1    1
[4,]   40   40   40   40   40
[5,]   50   50   50   50   50


[[4]]
[[4]]$A
     [,1] [,2] [,3] [,4] [,5]
[1,]   40   40   40   40   40
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

[[4]]$B
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]   20   20   20   20   20
[3,]   30   30   30   30   30
[4,]    1    1    1    1    1
[5,]   50   50   50   50   50


[[5]]
[[5]]$A
     [,1] [,2] [,3] [,4] [,5]
[1,]   50   50   50   50   50
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

[[5]]$B
     [,1] [,2] [,3] [,4] [,5]
[1,]   10   10   10   10   10
[2,]   20   20   20   20   20
[3,]   30   30   30   30   30
[4,]   40   40   40   40   40
[5,]    1    1    1    1    1

您可以试试下面的代码

list2env(
  setNames(
    Map(
      function(x, r) {
        x[1, ] <- r
        x
      },
      list(A, B),
      list(B[1, ], A[1, ])
    ), c("A", "B")
  ),
  envir = .GlobalEnv
)