100x100の行列が与えられた場合、20x20の行列を計算します。そのすべてのセルは、元の行列の5x5の正方形の平均を表します。
それを実行する方法は?(この操作に適した名前がある場合は、コメントして質問の名前を変更してください)。
ここにいくつかのオプションがあります。
簡単なアプローチはaggregate()
、ラスターパッケージから使用することです。
m <- matrix(1:10000, ncol=100)
library(raster)
r <- raster(m)
as.matrix(aggregate(r, 5))
## aggregate() also supports non-square aggregation windows
as.matrix(aggregate(r, c(20, 50)))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 975.5 2975.5 4975.5 6975.5 8975.5
# [2,] 1025.5 3025.5 5025.5 7025.5 9025.5
よりエレガントまたは難読化されたアプローチ(視点に応じて)には、2つの行列乗算を使用します。
m <- matrix(1:10000, ncol=100)
mm <- suppressWarnings(matrix(rep(c(1, rep(0, 20)), each=5), ncol=20, nrow=100))
(t(mm) %*% m %*% mm)/25
小さなおもちゃの例を見てみましょう。
R > mat = matrix(1:36, 6,6)
R > mat
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 7 13 19 25 31
[2,] 2 8 14 20 26 32
[3,] 3 9 15 21 27 33
[4,] 4 10 16 22 28 34
[5,] 5 11 17 23 29 35
[6,] 6 12 18 24 30 36
R > A = matrix(paste(ceiling(col(mat)/2), ceiling(row(mat)/2), sep = "-"), nc = ncol(mat))
R > A
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "1-1" "1-1" "2-1" "2-1" "3-1" "3-1"
[2,] "1-1" "1-1" "2-1" "2-1" "3-1" "3-1"
[3,] "1-2" "1-2" "2-2" "2-2" "3-2" "3-2"
[4,] "1-2" "1-2" "2-2" "2-2" "3-2" "3-2"
[5,] "1-3" "1-3" "2-3" "2-3" "3-3" "3-3"
[6,] "1-3" "1-3" "2-3" "2-3" "3-3" "3-3"
R > matrix(tapply(mat, A, mean), 3, 3)
[,1] [,2] [,3]
[1,] 4.5 16.5 28.5
[2,] 6.5 18.5 30.5
[3,] 8.5 20.5 32.5
このように、6 * 6行列の場合、各2 * 2ブロック行列を計算すると、3*3要約行列が得られます。
パーティーに遅れましたが、ここに行きます:
# width/height of the sub-squares
side <- 5
# test matrix
test <- outer(1:100,1:100)
# make a selection matrix categorising each cell
select <- matrix(
rep(1:(length(test)/(side^2)),each=side),
nrow=nrow(test)
)[,rep(1:(ncol(test)/side),each=side)]
# get the result
matrix(
sapply(1:(length(test)/(side^2)),function(x) mean(test[select==x])),
nrow=(ncol(test)/side)
)