Search code examples
rsubsetrasterterra

How to subset a SpatRasterDataset from the terra package?


I am trying to select several rasters from a SpatRasterDataset using the terra package in R. However when I try to select x rasters at once, the names show only the first x raster names, regardless of which rasters I try to select. Selecting a single raster seems to work fine, although the name given to it is not present.

So how do I properly subset a SpatRasterDataset keeping the correct names associated with rasters?

Reproducible example:

# Create SpatRasterDataset
r1 <- rast(matrix(1:100, nrow=10, ncol=10))
r2 <- rast(matrix(200:101, nrow=10, ncol=10))
r3 <- rast(matrix(c(2,200), nrow=10, ncol=10))
s <- sds(r1,r2,r3)

# Name rasters
names(s) <- c("A","B","C")
names(s)

# Add to list
l <- list(s)
l[[1]]
l[[1]][1:2] # shows rasters A,B
l[[1]][2:3] # also shows rasters A,B
l[[1]][c("B","C")] # shows rasters A,B
l[[1]][3] 
image(l[[1]][3]) # shows correct raster

# Subset SpatRasterDataset
s2 <- l[[1]][2:3] # select two rasters
names(s2) # names A, B
s2[1] # actually raster B
s2[2] # actually raster C

s3 <- l[[1]][3] # select one rasters
names(s3) # has some other name
s3 # has correct raster

Solution

  • The names of a SpatRasterDataset do not correspond to the (layer) names of a SpatRaster.

    With your example

    library(terra)
    r1 <- rast(matrix(1:100, nrow=10, ncol=10))
    r2 <- rast(matrix(200:101, nrow=10, ncol=10))
    r3 <- rast(matrix(c(2,200), nrow=10, ncol=10))
    s <- sds(r1,r2,r3)
    names(s) <- c("A","B","C")
    

    You can subset SpatRasterDataset s like this to get a new SpatRasterDataset:

    s[2:3]
    s[3, drop=FALSE]
    

    Or like this to get a SpatRaster

    s[3]
    

    "A", "B", and "C" are names of the sub-datasets (variables), not the (layer) names of the SpatRasters. These cannot be the same because each sub-dataset has a single name, whereas a SpatRaster can have many (layer-) names.

    For example, you might have

    rr1 <- c(r1, r2, r3)
    names(rr1) <- c("x", "y", "z")
    rr2 <- rr1[[1:2]] / 10
    rr3 <- r1 * 10
    ss <- sds(rr1,rr2,rr3)
    names(ss) <- c("A","B","C")
    
    ss 
    #class       : SpatRasterDataset 
    #subdatasets : 3 
    #dimensions  : 10, 10 (nrow, ncol)
    #nlyr        : 3, 2, 1 
    #resolution  : 1, 1  (x, y)
    #extent      : 0, 10, 0, 10  (xmin, xmax, ymin, ymax)
    #coord. ref. :  
    #source(s)   : memory 
    #names       : A, B, C 
    
    ss[1]
    #class       : SpatRaster 
    #dimensions  : 10, 10, 3  (nrow, ncol, nlyr)
    #resolution  : 1, 1  (x, y)
    #extent      : 0, 10, 0, 10  (xmin, xmax, ymin, ymax)
    #coord. ref. :  
    #sources     : memory  
                   memory  
                   memory  
    #varnames    : a 
    #              b 
    #              c 
    #names       :   x,   y,   z 
    #min values  :   1, 101,   2 
    

    A SpatRaster can have a variable name which you can set with

    varnames(r1) <- "A" 
    

    but that is probably not what you are after.