R:将 FUN 应用于数组的 kxk 子部分 [英] R: Apply FUN to kxk subsections of array

查看:17
本文介绍了R:将 FUN 应用于数组的 kxk 子部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

语言是 R.

我有一个 nxm 矩阵,我想将它分成 3x3 部分并计算每个部分的平均值(或任何函数).(如果有一个不是 3x3 的剩余部分,那么就使用剩下的部分).

I have an nxm matrix, and I'd like to partition it into 3x3 sections and calculate the mean (or any function) within each. (If there's a leftover bit that isn't 3x3 then use just what's left).

我确信有一种apply-ish 方式来做到这一点——它就在我的舌尖上——但我的大脑目前正在让我失望.我想这有点像移动窗口问题,只是我想要不重叠的窗口(所以更容易).

I'm sure there's an apply-ish way to do this -- it's on the tip of my tongue -- but my brain is currently failing me. I suppose it's a bit like a moving window question except I want non-overlapping windows (so it's easier).

谁能想到一个内置函数来做到这一点?还是矢量化的方式?

这是我的循环版本:

winSize <- 3
mat <- matrix(runif(6*11),nrow=6,ncol=11)
nr <- nrow(mat)
nc <- ncol(mat)
outMat <- matrix(NA,nrow=ceiling(nr/winSize),
                    ncol=ceiling(nc/winSize))
FUN <- mean
for ( i in seq(1,nr,by=winSize) ) {
    for ( j in seq(1,nc,by=winSize) ) {
        # work out mean in 3x3 window, fancy footwork
        #  with pmin just to make sure we don't go out of bounds
        outMat[ ceiling(i/winSize), ceiling(j/winSize) ] <-
               FUN(mat[ pmin(i-1 + 1:winSize,nr), pmin(j-1 + 1:winSize,nc)])
    }
}

干杯.

推荐答案

可以使用 rowcol 提取行号和列号,然后计算每个块的坐标.

You can use row and col to extract the row and column numbers, and then compute the coordinates of each block.

tapply( 
  mat, 
  list( floor((row(mat)-1)/winSize), floor((col(mat)-1)/winSize) ), 
  mean 
)

这可以推广到高维数组,通过用以下函数替换 rowcol.

This can be generalized to higher-dimensional arrays, by replacing row and col with the following function.

a <- function( m, k ) {
  stopifnot( "array" %in% class(m) || "matrix" %in% class(m) )
  stopifnot( k == floor(k) )
  stopifnot( k > 0 )
  n <- length(dim(m))
  stopifnot( k <= n )
  i <- rep(
    1:dim(m)[k],
    each  = prod(dim(m)[ 1:n < k ]),
    times = prod(dim(m)[ 1:n > k ])
  )  
  array(i, dim=dim(m))
}

# A few tests
m <- array(NA, dim=c(2,3))
all( row(m) == a(m,1) )
all( col(m) == a(m,2) )
# In dimension 3, it can be done manually:
m <- array(NA, dim=c(2,3,5))
all( a(m,1) == array( rep(1:dim(m)[1], times=prod(dim(m)[2:3])), dim=dim(m) ) )
all( a(m,2) == array( rep(1:dim(m)[2], each=dim(m)[1], times=dim(m)[3]), dim=dim(m) ) )
all( a(m,3) == array( rep(1:dim(m)[3], each=prod(dim(m)[-3])), dim=dim(m) ) )

这篇关于R:将 FUN 应用于数组的 kxk 子部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆