1

I am interested in the terra R package as it appears to be a successor to the raster package that is being more actively developed than the raster package. But it seems like some features are missing.

For example I have an aggregated National Landcover Dataset raster in .GRD format.

If I call x <- raster::raster('nlcd_agg.grd') the resulting object has a slot x@data@attributes with the raster attribute table that includes the names of the land cover types corresponding to the integer values in the raster.

However if I call x <- terra::rast('nlcd_agg.grd') I cannot find that attribute table in the object nor do I see how to associate the object x with the attribute table of the raster.

I would like to be able to load the raster and have the associated attribute table with land cover type names and default plotting colors load as well. I understand that .GRD is a native format for the raster package but is there some way to achieve this with the terra or stars packages?

Here are two small files that can replicate the behavior (nlcd_agg.grd and the associated nlcd_agg.gri):

3
  • Any chance you can point us to the file or one that shows the same behaviour?
    – Spacedman
    Commented Mar 26, 2021 at 22:44
  • @Spacedman see my edit which also has some clarifications
    – qdread
    Commented Mar 27, 2021 at 0:55
  • 1
    Can't see a way. Perhaps worth an issue to the terra issue tracker. I'm holding off terra until it all works better than raster and I do a bit of teaching with categorical land use data...
    – Spacedman
    Commented Mar 27, 2021 at 17:34

1 Answer 1

3

See the cats and levels methods. They are used to have rasters that behave like "factors". The issues you describe have been fixed in terra 1.1-17 (on its way to CRAN). For now, what you can do is something along these lines:

library(raster)
f <- "nlcd_agg.grd"
r <- raster(f)

library(terra)
x <- rast(r)

# get the attributes
lev <- levels(r)[[1]]  
lev <- lev[, c("ID", "Land.Cover.Class")]
lev[,2] <- as.character(lev[,2])

x <- rast(r)
levels(x) <- lev
is.factor(x)
#[1] TRUE

x
#class       : SpatRaster 
#dimensions  : 101, 121, 1  (nrow, ncol, nlyr)
#resolution  : 3750, 3750  (x, y)
#extent      : 1394535, 1848285, 1722765, 2101515  (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
#source      : memory 
#name        : nlcd_2011_landcover_2011_edition_2014_03_31 
#min value   :                                Unclassified 
#max value   :                                             

# legend shows class names    
plot(x)

Labels are returned as cell values

x[c(7357, 5047, 7360, 9307)]
#  nlcd_2011_landcover_2011_edition_2014_03_31
#1                          Perennial Snow/Ice
#2                                  Open Water
#3                          Perennial Snow/Ice
#4                                Unclassified

And the categories are stored if you save the raster to a GeoTIFF

z <- writeRaster(x, "test.tif", overwrite=TRUE)
z

ch

4
  • Thanks, very helpful. The other piece of it is that the attribute table of the .grd raster also contains columns Red,Green,Blue, and Opacity that are used in the default plot() method to color the land cover classes appropriately. Is that feature implemented in terra?
    – qdread
    Commented Mar 30, 2021 at 0:31
  • 1
    No, and I had forgotten about that. See my expanded answer for a work-around. I will improve this Commented Mar 30, 2021 at 3:59
  • Thanks for the workaround. This may not be related, but I have not been able to write the raster to a GeoTIFF. I get a segfault error when I call writeRaster(x, 'test.tif'). I have tried it on GDAL 2.2.2 and 3.0.4 and get the same error: caught segfault, memory not mapped.
    – qdread
    Commented Mar 30, 2021 at 12:16
  • there is one other issue: if I want to go the rats(x) route, the Land.Cover.Class column is coerced from a factor to numeric. I worked around this by first coercing it to character before calling rats(x) <- lev but just wanted to call it to your attention.
    – qdread
    Commented Apr 2, 2021 at 11:59

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.