R:具有最大值的列和行索引

R: column and row indices with largest values

假设我们有一个如下所示的矩阵:

-0.3  0.2   0.001  -0.4    0.5 
0.25  0.45  0.2    -0.001  0.02
0.8 - 0.2   0.35   0.1     0.1
0.25 -0.14  -0.1   0.02    0.4

现在我想找到矩阵中尺寸为 2 x 2 且其中具有最大元素(绝对值)的那部分。 所以这里将是以下索引:

2 1
2 2
3 1 
3 2

因为

0.25 0.4
0.8  -0.2

是矩阵中所有 2 x 2 矩阵中具有最大值的部分。

我如何在 R 中实现它?

我做了这个小例子,因为我的真实矩阵包含大约 4000 列和 5000 行,但这个矩阵中的许多值几乎为零。这很难形象化,因此我只想形象化最重要的部分。

您可以使用 which 来查找矩阵最大值的索引。

set.seed(1234)
mat <- matrix(sample(1:20), ncol = 5)
mat
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    3   14    8   20   17
# [2,]   12   10    6   15   16
# [3,]   11    1    7    2   19
# [4,]   18    4    5    9   13

which(mat == max(mat), arr.ind = TRUE)
#      row col
# [1,]   1   4

如果您正在寻找每列(或行)中的最大值,您可以使用:

apply(mat, 2, which.max)
# [1] 4 1 1 1 3

问题澄清后编辑

mrow <- nrow(mat); mcol <- ncol(mat)
subs <- list()
for (i in 1:(nrow(mat) - 1)) {
  for (j in 1:(ncol(mat) - 1)) {
    x <- c(i, j, i, j + 1, i + 1, j, i + 1, j + 1)
    subs[[paste0(i, j)]] <- matrix(x, ncol = 2, byrow = TRUE)
  }
}

sums <- sapply(subs, function (x) sum(abs(mat[x]))) 
win <- subs[[which(sums == max(sums))]]
mat[win[1, 1]:(win[1, 1] + 1), win[1, 2]:(win[1, 2] + 1)]
#      [,1] [,2]
# [1,]   20   17
# [2,]   15   16

我会很慢但是完成工作,这将给出所需子矩阵的行和列索引:

library(magrittr)

df = expand.grid(seq(nrow(mat)-1), seq(ncol(mat)-1)) 

vec = apply(df, 1, function(u){
              mat[u[1]:(u[1]+1),u[2]:(u[2]+1)] %>%
              abs %>%
              sum
      }) 

ind = df[which.max(vec),]
mat[ind[[1]]:(ind[[1]]+1),ind[[2]]:(ind[[2]]+1)]

#     [,1] [,2]
#[1,]   20   17
#[2,]   15   16

其中 mat 是:

mat = structure(c(3L, 12L, 11L, 18L, 14L, 10L, 1L, 4L, 8L, 6L, 7L, 
5L, 20L, 15L, 2L, 9L, 17L, 16L, 19L, 13L), .Dim = 4:5)

RcppRoll 提供了可能有用的快速滚动求和函数。这是一个比在大型矩阵上运行速度更快的答案:

n <- matrix(rnorm(4000*5000),nrow=4000,ncol=5000)


find_idx_max_square <- function(matrix) {
  library(RcppRoll)
  o <- apply(abs(matrix), 2,roll_suml,n=2L)
  p <- t(apply(o, 1,roll_suml,n=2L))
  idx <- which(p == max(p,na.rm=TRUE),arr.ind=TRUE)
  return(idx)
}

find_idx_max_square(n)
      row col
[1,] 1837 724

> system.time(find_idx_max_square(n))
utilisateur     système      écoulé 
  1.863          0.159       2.023 

说明

  1. 取矩阵matrix
  2. 计算每列所有后续两个元素的滚动总和(matrix[i,j] + matrix[i+1,j] for i in nrow(matrix) and j in ncol(matrix))。将其存储在新矩阵中 o
  3. 计算每列每行所有后续两个元素的滚动总和(matrix[i,j] + matrix[i,j+1] for i in nrow(matrix) and j in ncol(matrix) ).将其存储在一个新矩阵中 p.
  4. p 在每个单元格 [i,j] 中包含原始 [i,j][i+1,j][i,j+1][i+1,j+1] 的值总和=12=]
  5. 计算p的最大值。它给了我们最大和的2*2子矩阵左上角值的索引。