29

I have a raster stack, stk, consisting of three raster images in R. Here is a simple example

# set up a raster stack with three layers
> library(raster)
> r <- raster(nrows=10,ncols=10)
> r[] <- rnorm(100)
> stk <- stack(r,r,r)

# layer names are set by default
> names(stk)
[1] "layer.1" "layer.2" "layer.3"

I assign names to the raster layers:

# set layer names to "one", "two" and "three"
> names(stk) <- c('one','two','three')

> names(stk)
[1] "one" "two" "three"

When I write the RasterStack to a GeoTiff (multilayered) using:

writeRaster(stk,"myStack.tif", format="GTiff")

The layers are renamed based on the filename (see > names(stk) below).

When I read in the raster stack:

> stk <- stack("myStack.tif")

# the layer names have been set automatically based on the filename
# they should be "one", "two" and "three"
> names(stk)
[1] "myStack.1" "myStack.2" "myStack.3"

Do you know of any way to preserve the layer names when writing RasterStacks in R? I have tried writing the stack to GeoTIFF and NetCDF formats.

Thanks, Kevin

kguay
  • 391
  • 1
  • 3
  • 7
  • where are you reading the stacked tif file? – Paulo E. Cardoso Nov 06 '14 at 23:31
  • Paulo, Thank you for taking a look. I just cleaned up the example to make it more clear and fixed some of the wording. I read in the stacked tif file using `stk <- stack("myStack.tif")` (the first line of the last code block). Thanks again. – kguay Nov 07 '14 at 18:52

4 Answers4

14

You can make use of the native raster format:

myRaster <- writeRaster(stk,"myStack.grd", format="raster")

The raster grid format consists of the binary .gri file and the .grd header file. This will preserve your layernames. Note, however, that .gri binary files are not compressed.

If you need to open raster grd files in other programs you will most likely need to write an additional header file. I usually use the ENVI header format to do that.

hdr(myRaster, format = "ENVI")

To open the file from qgis for example you'd select the .gri file (the binary) and it should work.

bleutner
  • 535
  • 4
  • 8
  • Thanks for this answer! Reading the raster back in R, the layer names are preserved. However, QGIS is not able to show the correct layer names although they are correctly stored in both the .grd and the .hdr file. Is there a solution to this? – pat-s Mar 23 '17 at 17:21
  • 2
    Is it possible to store the layernames with the data in one file? Or does GeoTIFF simply not support layer naming? – Lucas Jun 15 '20 at 14:35
12

You can use terra or stars

Using terra

The names are preserved if you convert the stack into a rast object, from terra package

Then you can use raster::writeRaster or terra::writeRaster, either way, the names are preserved!

library(terra)
x <- rast(stk)
terra::writeRaster(x, "file.tif")
y <- raster::brick("file.tif") 
#y <- terra::rast("file.tif")
#y <- stars::read_stars("file.tif")
names(y)

Using stars

library(stars)
x <- st_as_stars(stk)
write_stars(x, "file2.tif")
y <- raster::brick("file2.tif")
#y <- terra::rast("file2.tif")
#y <- stars::read_stars("file2.tif")
names(y)
Sergio
  • 714
  • 1
  • 8
  • 24
10

A bit late but might help someone else looking for a possible solution:

writeRaster(stk, filename=names(stk), bylayer=TRUE,format="GTiff")
doncarlos
  • 401
  • 4
  • 16
  • 6
    This will write each layer into a separate file, not all layers and their names into one stack as per OP's question.. – shekeine Oct 03 '16 at 18:51
1

I wrote my files as ENVI files and changed the band names in the ENVI header file. The files can now be opened in ENVI and ArcGis and the layer names are preserved.

#write ENVI file (.envi; .hdr; .envi.aux.xml) with automatic layer names
writeRaster(stk, "myStack" , format="ENVI")

#change layer names in ENVI header (.hdr):
n="myStack.hdr"  
x <- readLines(n)
x <- gsub("Band 1,", "one,", x) 
x <- gsub("Band 2,", "two," , x)
x <- gsub("Band 3", "three", x)  
cat(x, file=n, sep="\n") #overwrites the old ENVI header

/edit I just noticed that when the .envi file is imported back into R the layer names are removed again. Same problem in SAGA.

image <- stack("myStack.envi")  
names(image)
#[1] "myStack.1" "myStack.2" "myStack.3"

image = readGDAL("myStack.envi") 
names(image)
#[1] "band1" "band2" "band3"
Iris
  • 1,072
  • 3
  • 10
  • 22