在R中同时移动矩阵的特定列和行的有效方法

Posted

技术标签:

【中文标题】在R中同时移动矩阵的特定列和行的有效方法【英文标题】:Efficient way to move specific columns and rows of a matrix at the same time in R 【发布时间】:2018-02-13 13:46:12 【问题描述】:

有一个看起来像这样的矩阵

  |A|B|C|D|E|F|
|A|_|_|_|_|_|_|
|B|_|_|_|_|_|_|
|C|_|_|_|_|_|_|
|D|_|_|_|_|_|_|
|E|_|_|_|_|_|_|
|F|_|_|_|_|_|_|

并通过在向量内指定要移动到矩阵末尾的行和列 e.i soi <- c("B", "D","E") 除了我的以下代码之外,还有什么更有效的方法来进行这种转换?

最终的矩阵应该是这样的

  |A|C|F|B|D|E|
|A|_|_|_|_|_|_|
|C|_|_|_|_|_|_|
|F|_|_|_|_|_|_|
|B|_|_|_|_|_|_|
|D|_|_|_|_|_|_|
|E|_|_|_|_|_|_|

我是通过这个函数实现的

prepare.tm <- function ( tm, soi )

  end_sets <- which(row.names(tm) %in% soi)
  ptm <- rbind( cbind(tm[-end_sets, -end_sets], tm[-end_sets, end_sets]) , cbind(tm[end_sets, -end_sets], tm[end_sets, end_sets]) )
  ptm

【问题讨论】:

【参考方案1】:

这是另一种方式:

a <- matrix(1:36, 6)
rownames(a) <- LETTERS[1:6]
colnames(a) <- LETTERS[1:6]
soi <- c("B", "D","E")
not.soi <- !(colnames(a) %in% soi)
ci <- c(colnames(a)[not.soi], soi)
a[ci, ci]
# > a[ci, ci]
#   A  C  F  B  D  E
# A 1 13 31  7 19 25
# C 3 15 33  9 21 27
# F 6 18 36 12 24 30
# B 2 14 32  8 20 26
# D 4 16 34 10 22 28
# E 5 17 35 11 23 29

这是一个带有整数索引的变体:

a <- matrix(1:36, 6)
rownames(a) <- LETTERS[1:6]
colnames(a) <- LETTERS[1:6]
soi <- c("B", "D","E")
i <- match(soi, colnames(a))
ci <- c((1:ncol(a))[-i], i)
a[ci, ci]

这是一个基准:

jogo.chr <- function ( tm, soi ) 
  not.soi <- !(colnames(tm) %in% soi)
  ci <- c(colnames(tm)[not.soi], soi)
  tm[ci, ci]


jogo.int <- function ( tm, soi ) 
  i <- match(soi, colnames(tm))
  ci <- c((1:ncol(tm))[-i], i)
  tm[ci, ci]


prepare.tm <- function ( tm, soi )

  end_sets <- which(row.names(tm) %in% soi)
  ptm <- rbind( cbind(tm[-end_sets, -end_sets], tm[-end_sets, end_sets]) , cbind(tm[end_sets, -end_sets], tm[end_sets, end_sets]) )
  ptm


library("microbenchmark")
N <- 25
a <- matrix(1:(N*N), N)
rownames(a) <- LETTERS[1:N]
colnames(a) <- LETTERS[1:N]
soi <- c("B", "D","E")
microbenchmark(prepare.tm(a, soi), jogo.chr(a, soi), jogo.int(a, soi), unit="relative")
# > microbenchmark(prepare.tm(a, soi), jogo.chr(a, soi), jogo.int(a, soi), unit="relative")
# Unit: relative
#               expr      min       lq     mean   median       uq      max neval cld
# prepare.tm(a, soi) 2.754785 2.670412 2.577385 2.629260 2.597874 2.838851   100   c
#   jogo.chr(a, soi) 1.596205 1.590862 1.645833 1.597474 1.579997 2.241035   100  b 
#   jogo.int(a, soi) 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000   100 a  

【讨论】:

以上是关于在R中同时移动矩阵的特定列和行的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

QTableView 将视图重新聚焦到特定列

在 SQL 中转置列和行的简单方法?

如何识别两个数据矩阵之间的哪些列和行匹配?

重新排序矩阵元素以反映朴素python中的列和行聚类

R中非常大的矩阵计算有效

创建一个可以在 React 上拖放列和行的表