rspatialterradownsamplingregrid

Downsampling with terra to arbitrary grids, resample() and project() only subset


I want to downsample model output to a coarser, arbitrary new grid. aggregate() does not do the trick, as I want to arrive at a specific grid. For some reason, resample() and project() only return a "zoomed" subset and not the desired product: the aggregated/downsampled data on a new grid.

I feel that the solution must be very obvious, but i could not find anything on stackoverflow/rseek at all.

Here is some example code:

library(terra)
# dummy starting raster
raw <- rast(ext(c(-0.5625, 359.4375, -89.70215791342, 89.70215791342)),nrow=160,ncol=320)
# with some "structure" to see the changes
values(raw) <- (1:ncell(raw))/10000+c(rep(1,ncell(raw)/4),rep(2,ncell(raw)/4),rep(1,ncell(raw)/4),rep(2,ncell(raw)/4))
# correct specs:
raw
plot(raw)

#desired new projection(?)
newgrid <- rast(xmin=1,xmax=128,ymin=1,ymax=64,nrow=64,ncol=128)#,crs="wgs84"

#modify with resample or project
new1 <- project(raw,newgrid,method="bilinear")
new2 <- resample(raw,newgrid,method="bilinear")

#that created only a subset/"zoom" and not a new map with different grid
plot(new1)
plot(new2)

I tried aggregate, resample and project functions of terra package in different variants. I want to transform my starting rast to a new one with the desired extent, resolution, etc. Aggregation does not work, because I want to have a specific grid; resample and project return only a subset instead of the full set of values on the new grid.

sessioninfo: enter image description here


Solution

  • As @Chris noted, the extent of newgrid is smaller than that of raw, so only the overlapping areas will be resampled(). Note that even though terra::rast() has assigned WGS84/EPSG:4326 to your SpatRasters by default, it is good practice to do it explicitly.

    To illustrate the issue:

    library(terra)
    library(ggplot2)
    library(tidyterra)
    
    # dummy starting raster
    raw <- rast(ext(c(-0.5625, 359.4375, -89.70215791342, 89.70215791342)), 
                nrow = 160,
                ncol = 320,
                crs = "EPSG:4326")
    
    values(raw) <- (1:ncell(raw))/10000 + c(rep(1,ncell(raw)/4),rep(2,ncell(raw)/4),
                                            rep(1,ncell(raw)/4),rep(2,ncell(raw)/4))
    
    
    newgrid <- rast(ext(1, 128, 1, 64),
                    nrow = 64,
                    ncol = 128,
                    crs = crs(raw))
    
    new <- resample(raw, newgrid, method = "bilinear")
    
    # For illustrative purposes
    v1 <- vect(ext(raw), crs = "EPSG:4326")
    v2 <- vect(ext(newgrid), crs = "EPSG:4326")
    
    ggplot() +
      geom_spatvector(data = v1,
                      aes(colour = "raw\nextent")) +
      geom_spatraster(data = new) +
      geom_spatvector(data = v2,
                      aes(colour = "newgrid\nextent"),
                      lwd = 1,
                      fill = NA) +
      scale_colour_manual(name = "", values = c("firebrick", "black")) +
      theme_void()
    

    1

    One way to ensure your resampled Spatraster retains its original extent:

    # Create new Spatraster with lower resolution, same extent as raw
    newgrid <- rast(ext(raw), nrow = 64, ncol = 128, crs = "EPSG:4326")
    
    # Resample raw using newgrid
    new <- resample(raw, newgrid, method = "bilinear")
    
    raw
    # class       : SpatRaster 
    # dimensions  : 160, 320, 1  (nrow, ncol, nlyr)
    # resolution  : 1.125, 1.121277  (x, y)
    # extent      : -0.5625, 359.4375, -89.70216, 89.70216  (xmin, xmax, ymin, ymax)
    # coord. ref. : lon/lat WGS 84 (EPSG:4326) 
    # source(s)   : memory
    # name        :  lyr.1 
    # min value   : 1.0001 
    # max value   : 7.1200 
    
    new
    # class       : SpatRaster 
    # dimensions  : 64, 128, 1  (nrow, ncol, nlyr)
    # resolution  : 2.8125, 2.803192  (x, y)
    # extent      : -0.5625, 359.4375, -89.70216, 89.70216  (xmin, xmax, ymin, ymax)
    # coord. ref. : lon/lat WGS 84 (EPSG:4326) 
    # source(s)   : memory
    # name        :    lyr.1 
    # min value   : 1.032195 
    # max value   : 7.087905