Search code examples
rfunctionfor-loopmatrixraster

iterating through raster bands to perform calculation


i've been trying to run this code, but i receive the error: non-numeric argument to binary operator. i've tried stacking and then iterating through them to perform a calculation. it, unfortunately, doesn't work right. it messes with the raster band metadata and appears to condense all the bands into one image rather than nine seperate ones. so i'm trying to do it without stacking the bands and instead iterate running them through a equation. any suggestions?

i'm attempting to run this calculation by using two lists of raster bands, one "red" and the other is "nir". each list contains nine raster bands and the lists are in order so that the first raster band in one list is from the same image as the first raster band in the other list. i've tried adding as.numeric, but it's still not working - perhaps i didn't enter it correctly.

subfolders <- '~/Desktop/hls project/fieldszn'
bands <- list.files(subfolders, pattern = ".tiff", recursive = TRUE, full.names = TRUE)

red = list(list.files(subfolders, pattern = "red", full.names = TRUE, recursive = TRUE))
nir = list(list.files(subfolders, pattern = "nir", full.names = TRUE, recursive = TRUE))


calculate_ndvi <- function(nir, red){
  ndvi <- (nir-red)/(nir+red)
  return(ndvi)}


ndvi <- list()
for (i in 1:9){ 
  ndvi[[i]] <- (calculate_ndvi(nir[[i]], red[[i]]))
}

Solution

  • It should work like this

    library(terra)
    # do not make a list
    red <- list.files(pattern = "red")
    nir <- list.files(pattern = "nir")
    
    calc_ndvi <- function(nir, red) {
      (nir-red)/(nir+red)
    }
    
    ndvi <- list()
    for (i in 1:9){ 
      ndvi[[i]] <- calc_ndvi(rast(nir[i]), rast(red[i]))
    }
    ndvi <- rast(ndvi)
    

    But you can also do them all at once like this

    ndvi <- calc_ndvi(rast(nir), rast(red))
    

    Or like this

    s <- sds(rast(red), rast(nir))
    ndvi <- lapp(s, calc_ndvi)