0
votes

I am working with time series of rasters and I need to analyse a ts of 17 dates. For each date, I imported band 5 and band 7. I made a list of the 17 bands-5 and a list of the 17 bands-7, called respectively list_B5 and list_B7. I would like to stack together bands of the same date, so: the first raster of list_B5 with the first raster of list_B7; the second raster of list_B5 with the second raster of list_B7; and so on.

I am new to loops, but I tried to write one:

    for (i in seq_along(length(list_B5)) [1]) {
      for (j in seq_along(length(list_B7)) [2]) {
        B5 <- raster(list_B5[[i]]) #extract the raster of interest
        B7 <- raster(list_B7[[j]]) #extract the raster of interest
        test[i,j] <- brick(B5, B7) #stack them together
      }
    }

with "test" being:

test <- brick(nrows=5490, ncol=5490, nl=17)

Unfortunately I get the following error:

Error in (function (classes, fdef, mtable)  : 
unable to find an inherited method for function ‘raster’ for signature ‘"NULL"’

I do not understand why it doesn't accept the lines in which I try to extract the raster of interest, since this line alone usually works:

> raster(list_B5[[3]])
class       : RasterLayer 
dimensions  : 5490, 5490, 30140100  (nrow, ncol, ncell)
resolution  : 20, 20  (x, y)
extent      : 6e+05, 709800, 5590200, 5700000  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 

Can someone explain to me why I get the above mentioned error?

1
If you want to stack B5 and B7 from the same date, why do you use i and j? Also, why do you use i with [1] and j with [2]? I recommend you detele j loop and use only i. If test is a list, use test[[i]] <- brick(B5, B7)aldo_tapia

1 Answers

1
votes

Why your code is broken

seq_along(length(list_B5)) is not doing what you expect it to. Rather, it just returns 1. You would need to use either seq_along(list_B5), or seq_len(length(list_B5)). Take a look at the docs for info.

Later, you subset 1 to its second element: seq_along(length(list_B7))[2]. This introduces an NA, which causes problems later on.

You can debug these issues on your own, by testing parts of your code to see if they produce the expected result. E.g., run seq_along(length(list_B5))[1] and seq_along(length(list_B7))[2] and see if they generate the sequences you hoped for.


A simpler way

It's probably easiest to do this with mapply.

list_b5 <- replicate(17, raster(matrix(runif(12), ncol=3)))
list_b7 <- replicate(17, raster(matrix(runif(12), ncol=3)))

mapply(stack, list_b5, list_b7)

Here, mapply loops over elements of list_b5 and list_b7 simultaneously, and applies the stack function (replace with brick if you prefer).

If your lists are actually file paths, then you can do:

list_b5 <- replicate(17, raster(matrix(runif(12), ncol=3)))
list_b7 <- replicate(17, raster(matrix(runif(12), ncol=3)))

mapply(function(x, y) stack(raster(x), raster(y)), list_b5, list_b7)

To fix your approach

And here's how you'd do it with a for loop:

test <- list(length=17)
for (i in seq_along(list_b5)) {
    b5 <- list_b5[[i]]
    b7 <- list_b7[[i]]
    test[[i]] <- stack(b5, b7)
}

or if your lists are file paths,

test <- list(length=17)
for (i in seq_along(list_b5)) {
    b5 <- raster(list_b5[[i]])
    b7 <- raster(list_b7[[i]])
    test[[i]] <- stack(b5, b7)
}