10

How do I subset a SpatRaster from the R terra package by value? This is the raster:

> rh10
class       : SpatRaster 
dimensions  : 2732, 4379, 1  (nrow, ncol, nlyr)
resolution  : 1000, 1000  (x, y)
extent      : -1950750, 2428250, -1785500, 946500  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=lcc +lat_0=42.5 +lon_0=-100 +lat_1=25 +lat_2=60 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs 
source      : memory 
name        :     vp_1 
min value   : 0.096915 
max value   : 1.291845 
time        : 2009-01-01 12:00:00 

> typeof(rh10)
[1] "S4"

The raster has relative humidity values in the cells. I inspected the raster.


> summary(rh10)
      vp_1      
 Min.   :0.106  
 1st Qu.:0.513  
 Median :0.594  
 Mean   :0.581  
 3rd Qu.:0.678  
 Max.   :1.283  
 NA's   :22329  
Warning message:
[summary] used a sample 

Because it's supposed to be relative humidity, I was expecting values less than 1. I guess greater than 1 is possible, but I'm trying to figure out which cells in the raster are over 1. I can't figure out how to subset the raster to begin with.

> length(rh10$vp_1 > 1.0)
[1] 1
> length(rh10 > 1.0)
[1] 1
> rh10[rh10[]> 1.0]
Error in rh10[rh10[] > 1] : object of type 'S4' is not subsettable

How should I go about figuring which are the uncommon cells? I'd like to see how many there are and where specifically they occur in the raster? Even my idea of subsetting is not correct, I'd like to know how I should properly subset the raster by cell values in addition to answering the related questions of how many and where.

2 Answers 2

14

With these example data

library(terra)
f <- system.file("ex/elev.tif", package="terra")
r <- rast(f)
r
#class       : SpatRaster 
#dimensions  : 90, 95, 1  (nrow, ncol, nlyr)
#resolution  : 0.008333333, 0.008333333  (x, y)
#extent      : 5.741667, 6.533333, 49.44167, 50.19167  (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84 (EPSG:4326) 
#source      : elev.tif 
#name        : elevation 
#min value   :       141 
#max value   :       547 

Say you want to set values over 300 to 300

x <- clamp(r, upper=300)

Or to NA

x <- clamp(r, upper=300, value=FALSE)

You can also use ifel

y <- ifel(r > 300, 300, r)

Or classify

z <- classify(r, cbind(300, Inf, 300))

It is best to avoid approaches like the one below. They are inefficient and not safe with large datasets.

r[r > 300] <- NA

There is no specific method to subset multiple values (as suggested in a comment), but you could do

y <- subst(r, c(280, 284, 295, 300), c(280, 284, 295, 300), others=NA)
#or
y <- mask(r, r, c(280, 284, 295, 300), inverse=TRUE)

Or (a less favorably viewed) equivalent

y <- mask(r, r %in% c(280, 284, 295, 300), maskvalue=FALSE)
5
  • If the last is not safe, then can | should this be avoided: ## Hib RC[s == 1 & a == 1 | a == 2] <- 1 ## Food RC[s == 1 & a == 1] <- 1 ## Hib RC[s == 2 & a == 1 | a == 2] <- 2 ## Food RC[s == 2 & a == 1 | s == 1 & a == 2] <- 2 Commented Jul 19, 2022 at 4:07
  • Comments are not a good place to ask a new question Commented Jul 19, 2022 at 6:19
  • Agreed, but I was not sure if it was sufficient enough of a stand-alone question as it is tied to your final point of "best to avoid". I am curious as to the danger involved here. If I need to avoid, then I need to find another way to build new rasters (e.g., RC) based on logical conditions in others (e.g., s, a; as in example given). If this seems sufficient for a stand alone question, then I will post it separately. Commented Jul 19, 2022 at 17:28
  • 1
    Your example is more complex, and worthy of a question, I think Commented Jul 19, 2022 at 18:30
  • Regarding the original answer: what if i want to create a subset of certain values, say, 280, 284, 295 and 300? In this case, using the > operator wouldn't cut it. Isn't there an efficient way to subset it? Normally, I would use the approach you condemned, but it doesn't seem to be working with SpatRasters...
    – Eric Lino
    Commented Jun 7, 2023 at 15:49
4

Either use only the > operator to make a boolean raster of the values over 1.

library(terra)

rast <- terra::rast("path/to/my.tif")

gt.1 <- rast > 1

plot(gt.1)

enter image description here

Or if you want to filter the true values, you can set the rest to NA:

rast <- terra::rast("path/to/my.tif")

rast[rast < 1] <- NA

plot(rast)

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.