I have a RasterStack object from witch I need to take some layers into a new RasterStack. To to that I've created a loop. My problem in that I am losing my original layers names in the process. As you will see below, when I take just one of the layers without the loop, the original name are kept.

In addition I also need to group the layers (variables) into models, so I can iterate though the variables inside each model with a bigger loop I'm building.

How do I extract layers from a raster keeping the original layer naming?

Here is some exemple..

## stk1 is the original RasterStack
## stk1 has 3 models in it (.1,.2,.3) each model has 4 variables (day1, day2, day3, day 4)
[1] "day1.1" "day2.1" "day3.1" "day4.1"
[5] "day1.2" "day2.2" "day3.2" "day4.2"
[9] "day1.3" "day2.3" "day3.3" "day4.3"

Here is the loop i've got running.

## Selecting day2 and day4 from stk1
variables <- as.factor(c("day2.1", "day4.1", 
                         "day2.2", "day4.2",
                         "day2.3", "day4.3"))

for (i in 1:length(variables))
  writeRaster(stk1[[i]], filename = paste0("./data/stk1-", variables[i], ".grd"), format = "raster", bylayer = TRUE) # I've tried with and without bylayer.

stk1_select  <- stack(list.files("./data/", pattern = ".grd$", full.names = TRUE))
names(stk1_select) **# this names should be exactly as it is in variables**
[1] "day3.1" "day1.1"
[5] "day2.1" "day4.1"
[9] "day4.2" "day2.2"

Extracting one by one does keep the original layer name.

writeRaster(stk1[["day2.1"]], filename = paste0("./data/stk-", "day2.1", ".grd"), format = "raster")
day2.1 <- raster("./data/stk-day2.1.grd")
[1] "day2.1"

Finally what I need is like an array of rasters. stk1_select should be modelA( var: day2, day4), modelB (var: da2, day4), modelC (day2, day4)

1 Answer 1


You have to select which layer you want to save. i in 1:length(variables) select layer[[1]], layer[[2]], ... , layer[[length(variables)]]. The first layer you want to save is not layer[[1]], is layer[[2]], so is necessary to specify each layer name. Here I present you a way to select specific layer into a loop using which() function:


r <- raster()

r[] <- 1

stk1 <- stack(r,r,r,r,r,r,r,r,r,r,r,r)

idx <- paste0('day',rep(1:4,each=3),'.',rep(1:3))

names(stk1) <- idx

variables <- as.factor(c("day2.1", "day4.1", 
                         "day2.2", "day4.2",
                         "day2.3", "day4.3"))

for (i in variables)
  writeRaster(stk1[[which(names(s) %in% i)]], filename = paste0("./data/stk1-", i, ".grd"), format = "raster")

stk1_select  <- stack(list.files("./data/", pattern = ".grd$", full.names = TRUE))
## [1] "day2.1" "day2.2" "day2.3" "day4.1" "day4.2" "day4.3"

You can also reorder layers to match with the specific position in variables vector:

stk1_reselect <- stk1_select[[match(variables,names(stk1_select))]]
## [1] "day2.1" "day4.1" "day2.2" "day4.2" "day2.3" "day4.3"

Create stack for each model:

mdls <- paste0('.',1:3,'.grd$')


modellist<- lapply(mdls, function(x){stack(list.files("./data/", pattern = x, full.names = TRUE))})
  • I have not tried you approach yet. It makes sense, though. To avoid another post, could you make an edit to you answer, showing how to give names to the models? Day1.1 day2.1 is part of model A, for instance. I’m constructing a bigger function which needs to iterate through the layers within each model. In the exemple it should be returned 3 models each containing its own set of raster layers. Commented Aug 16, 2018 at 20:19
  • @MiltonAlves sure, but can you edit your question adding some code to obtain models? Cause could be a nested iteration or a simple one to reach this
    – aldo_tapia
    Commented Aug 16, 2018 at 20:26
  • Sure. See my post edit. If I did not make myself clear, let me know. I cold also create another post if it is pertinent. Commented Aug 16, 2018 at 20:42
  • @MiltonAlves ready... a stack for each model inside a list
    – aldo_tapia
    Commented Aug 16, 2018 at 21:36
  • What is s in names(s)? Commented Aug 16, 2018 at 22:29

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.