Save as tif after stack with names of a dataframe

I am working with raster time-series files in R, I use stack in order to make some calculation which is scale factor and crop them in my AOI. When I plot them it is OK I can see 16plots of 728 (it is ok code runs perfect), after I can save also as multilayer:

writeRaster(a, filename="multilayer.tif", options="INTERLEAVE=BAND", overwrite=TRUE)

I have created a data frame with the dates of each raster using the sub_string, from names of each raster file. My final goal is to save each stacked file separately with the name of the data frame. I tried with no success, where
a: my stacked raster files
name: data frame with dates. Here is my code:

names <- paste0("Day", name, format=".tif")
writeRaster(a, filename = names(name), bylayer=T)

and I get the following error: Error in (function (classes, fdef, mtable):unable to find an inherited method for function ‘writeRaster’ for signature ‘"RasterBrick", "NULL"’

I do not want to have it as a multilayer file, but I need to have each raster saved as it is described above.

Given the documentation for the writeRaster() function, your code should work, however it looks like it hasn't been implemented for a RasterBrick object (I don't know why this is).

That said, I think you can accomplish what you're trying to do using iteration and the raster() function, which creates a single-layer raster object. From a RasterBrick, the syntax would look like raster(brick_object, layer = 1). From there, you can write the (now single-band) raster to disk. Using the longlake_osm object in the ggspatial package (a raster brick with 3 layers), your code might look like this:

library(raster)
#> Loading required package: sp
ggspatial::load_longlake_data()

longlake_osm
#> class       : RasterBrick 
#> dimensions  : 471, 553, 260463, 3  (nrow, ncol, ncell, nlayers)
#> resolution  : 3.33, 3.32  (x, y)
#> extent      : 409891.4, 411732.9, 5083289, 5084853  (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
#> data source : /Library/Frameworks/R.framework/Versions/3.5/Resources/library/ggspatial/longlake/longlake.tif 
#> names       : longlake.1, longlake.2, longlake.3 
#> min values  :         25,         74,         46 
#> max values  :        255,        255,        255

# with a single band, this is how to extract it as a separate raster
single_band <- raster(longlake_osm, layer = 1)
writeRaster(single_band, "layer_1.tif")

# for multiple bands, I think this works well in a for() loop
layer_filenames <- c("red.tif", "green.tif", "blue.tif")
for(i in 1:3) {
  single_band <- raster(longlake_osm, layer = i)
  writeRaster(single_band, layer_filenames[i])
}

If you are familiar with the purrr package, you could also write the loop as an "apply-the-function-along-the-list" approach:

library(raster)
#> Loading required package: sp
library(purrr)
ggspatial::load_longlake_data()

layer_filenames <- c("red.tif", "green.tif", "blue.tif")
layers_list <- map(1:3, ~raster(longlake_osm, layer = .))

# use walk2 rather than map2 because we don't want the output
# of writeRaster
walk2(layers_list, layer_filenames, writeRaster)

Created on 2019-04-27 by the reprex package (v0.2.1)

I think it's because you are providing names(name) as an argument instead of just names. names() is also a built-in function, but the name character vector here probably has no names attribute attached to its elements, so this function returns NULL. And this does not match the signature of the writeRaster() method, which expects a string for its second argument, not NULL.

However your names vector might also not be properly constructed in the first place. It's hard to know the correct solution without knowing the structure of the data frame, but the following would be valid if the filenames you want are constructed from the column names of the name data frame:

fnames <- paste0("Day", names(name), format=".tif")
writeRaster(a, filename = fnames, bylayer=T)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.