在R中调整矩阵大小的函数

use*_*730 9 r matrix

我想知道是否有一个功能可以缩小R统计软件中的矩阵,就像图像大小调整一样.imresize()MATLAB中的函数正是我正在寻找的(我相信它需要周围点的平均值,但我不确定这个),但我想知道这个函数是否有R等价物.

这个问题之前已经发布在这个论坛上,但是参考了MATLAB,而不是R: Matlab"缩小"一个平均值向量帖子以"你不能使用该imresize()函数的任何理由?" 开头.正是我在寻找,但在R,而不是MATLAB.

假设我有一个世界各地的经度 - 纬度经度网格,让我们说这是由64*128的温度矩阵表示的.现在让我们说我希望在新矩阵中包含相同的数据,但我想重新调整我的网格,使其成为全球71*114的温度矩阵.一个允许我这样做的函数是我正在寻找的(再次,imresize()函数,但在R中,而不是MATLAB)

谢谢.史蒂夫

Jos*_*ien 11

要做到这一点的方法之一是使用功能resample(),从raster包.

我将首先展示如何使用它来重新缩放网格,然后为更小的栅格对象提供更容易检查的应用示例

使用resample()以调整矩阵

library(raster)
m <- matrix(seq_len(68*128), nrow=68, ncol=128, byrow=TRUE)

## Convert matrix to a raster with geographical coordinates
r <- raster(m)
extent(r) <- extent(c(-180, 180, -90, 90))

## Create a raster with the desired dimensions, and resample into it
s <- raster(nrow=71, ncol=114)
s <- resample(r,s)

## Convert resampled raster back to a matrix
m2 <- as.matrix(s)
Run Code Online (Sandbox Code Playgroud)

视觉确认resample()你做了你想做的事:

library(raster)
## Original data (4x4)
rr <- raster(ncol=4, nrow=4)
rr[] <- 1:16
## Resize to 5x5
ss <- raster(ncol=5,  nrow=5)
ss <- resample(rr, ss)
## Resize to 3x3
tt <- raster(ncol=3, nrow=3)
tt <- resample(rr, tt)
## Plot for comparison
par(mfcol=c(2,2))
plot(rr, main="original data")
plot(ss, main="resampled to 5-by-5")
plot(tt, main="resampled to 3-by-3")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Vyg*_*yga 6

Josh O'Brien发布的答案很好,它帮助了我(起点),但这种方法很慢,因为我有大量的数据.以下方法是很好的选择.它使用fields和工作得更快.

功能

rescale <- function(x, newrange=range(x)){
  xrange <- range(x)
  mfac <- (newrange[2]-newrange[1])/(xrange[2]-xrange[1])
  newrange[1]+(x-xrange[1])*mfac
}

ResizeMat <- function(mat, ndim=dim(mat)){
  if(!require(fields)) stop("`fields` required.")

  # input object
  odim <- dim(mat)
  obj <- list(x= 1:odim[1], y=1:odim[2], z= mat)

  # output object
  ans <- matrix(NA, nrow=ndim[1], ncol=ndim[2])
  ndim <- dim(ans)

  # rescaling
  ncord <- as.matrix(expand.grid(seq_len(ndim[1]), seq_len(ndim[2])))
  loc <- ncord
  loc[,1] = rescale(ncord[,1], c(1,odim[1]))
  loc[,2] = rescale(ncord[,2], c(1,odim[2]))

  # interpolation
  ans[ncord] <- interp.surface(obj, loc)

  ans
}
Run Code Online (Sandbox Code Playgroud)

让我们看看它是如何工作的

## Original data (4x4)
rr <- matrix(1:16, ncol=4, nrow=4)
ss <- ResizeMat(rr, c(5,5)) 
tt <- ResizeMat(rr, c(3,3)) 

## Plot for comparison
par(mfcol=c(2,2), mar=c(1,1,2,1))
image(rr, main="original data", axes=FALSE)
image(ss, main="resampled to 5-by-5", axes=FALSE)
image(tt, main="resampled to 3-by-3", axes=FALSE)
Run Code Online (Sandbox Code Playgroud)

调整大小的矩阵