取R中矩阵内的块总和

时间:2018-04-18 20:27:16

标签: r matrix

我有以下9x9矩阵。

m<-matrix(runif(9*9), nrow = 9, ncol=9)
m

     [,1]       [,2]       [,3]       [,4]       [,5]       [,6]       [,7]       [,8]       [,9]
[1,] 0.2449707 0.81326836 0.72297582 0.03551436 0.82410051 0.29909943 0.13396759 0.71995057 0.03458879
[2,] 0.2715794 0.08984877 0.36775262 0.87896437 0.51941450 0.31631194 0.19142086 0.80257639 0.05081064
[3,] 0.3741446 0.05950594 0.87952538 0.45086034 0.20399313 0.42205156 0.10122543 0.04948101 0.58620932
[4,] 0.8472067 0.56675295 0.52710442 0.35257950 0.70820007 0.30591402 0.25243479 0.81976209 0.06595630
[5,] 0.1034456 0.18511441 0.70661040 0.59577040 0.87518085 0.16782022 0.98967611 0.96391309 0.86283653
[6,] 0.3685605 0.08227258 0.24782776 0.12557143 0.97220534 0.70517827 0.01113961 0.19896752 0.45398202
[7,] 0.1305617 0.29664856 0.21321683 0.83940964 0.91064918 0.67109195 0.92055064 0.08246438 0.86575867
[8,] 0.8799545 0.52515529 0.09592935 0.43177214 0.62089808 0.04079269 0.62836857 0.70525627 0.04421984
[9,] 0.4941711 0.28413734 0.02130229 0.77447519 0.02323584 0.52432477 0.02130935 0.42077756 0.02348518

如何在此矩阵中取每个3x3块的总和,得到以下3x3矩阵?

     [,1]       [,2]       [,3]
[1,] 2.04235671 3.95031014 2.6702306
[2,] 3.63489532 4.8084201  4.61866806
[3,] 2.94107696 4.83664948 3.71219046

提前致谢!

4 个答案:

答案 0 :(得分:2)

如果我们借用matsplitter function from this question我们可以做到

set.seed(15)
m<-matrix(runif(9*9), nrow = 9, ncol=9)
matrix(apply(matsplitter(m, 3, 3), 3, sum), ncol=3)
#          [,1]     [,2]     [,3]
# [1,] 5.067493 5.293779 5.342015
# [2,] 4.003959 4.901462 5.236655
# [3,] 6.319576 4.953201 5.571824

与真正的答案很匹配

sum(m[1:3, 1:3])
# [1] 5.067493
sum(m[1:3, 4:6])
# [1] 4.003959
sum(m[4:6, 1:3])
# [1] 5.293779
sum(m[7:9, 7:9])
# [1] 5.571824

答案 1 :(得分:1)

这里的其他答案可能更好/更快,但你也可以循环遍历块

set.seed(15)
m <- matrix(runif(9*9), nrow = 9, ncol=9)

blocksz <- 3
out <- matrix(NA, blocksz, blocksz)
for(i in 1:(nrow(m)/blocksz)){
  for(j in 1:(ncol(m)/blocksz)){
    iblock <- (1:blocksz) + blocksz*(i - 1)
    jblock <- (1:blocksz) + blocksz*(j - 1)
    out[i, j] <- sum(m[iblock, jblock])
  }
}

tidyverse

seq_len(nrow(m)/blocksz) %>% 
  expand.grid(., .) %>% 
  pmap_dbl(~sum(m[1:blocksz + blocksz*(.x - 1), 
                  1:blocksz + blocksz*(.y - 1)])) %>% 
  matrix(blocksz, byrow = T)

答案 2 :(得分:0)

选项可以是:

set.seed(15)
m<-matrix(runif(9*9), nrow = 9, ncol=9)

split_lst <- split(m, rep(1:3, each=9*3))

mod_m <- cbind(matrix(split_lst[[1]], nrow=3, byrow = TRUE),
               matrix(split_lst[[2]], nrow=3, byrow = TRUE),
               matrix(split_lst[[3]], nrow=3, byrow = TRUE))


sapply(split(colSums(mod_m), rep(1:9, each=3)),sum)

# 1        2        3        4        5        6        7        8        9 
# 5.067493 5.293779 5.342015 4.003959 4.901462 5.236655 6.319576 4.953201 5.571824

答案 3 :(得分:0)

您还可以创建模板:

tmp <- structure(c(1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 
 2, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4, 5, 5, 
5, 6, 6, 6, 5, 5, 5, 6, 6, 6, 5, 5, 5, 6, 6, 6), .Dim = c(6L, 
9L))

然后做这样的事情:

matrix(sapply(1:6,function(x) sum(m[which(tmp == x)])),3,3)