I have a very specific script I am trying to make which computes image flatfields. Basically, I am computing a Master Dark Frame (MD) by averaging a set of Dark Photos.

I have a set of light photos as well. I want to take the averaged dark photo and subtract that average from each light photo within a directory. After this, a Master Flat (MF) is made by averaging all the light photos which had been subject to dark frame subtractions.

Here is my script so far:

##Takes all dark frame images from within working directory and stacks them   into a single object 
darkrastdat<- list.files()
darkstack<- stack(darkrastdat)
##computes the mean of all dark layers/pixels within the object, omits no- data values 
masterdark <- mean(darkstack, na.rm=TRUE)

##loads each light frame into an object 
lightrastdat<- list.files()

##subtracts master dark from each light frame 

##stacks and averages light frames 

##writes master flat as 16-bit into original working directory
writeRaster(mrast, filename= "MF.tif", datatype='INT2U', overwrite=TRUE)

I am able to get an master dark frame (MD) from within a directory of photos. I am having trouble coming up with a way to subtract that MD from each light frame individually.

Can anyone give me some advice?

  • Are you just trying to subtract one raster from another? r3 = r2 - r1 works if r1 etc are raster objects.
    – Spacedman
    Feb 26, 2017 at 21:33
  • Hey Spacedman - I want to do just that - but I'd like to subract one raster from 20 files in a directory. i.e the Raster1 - MasterFlat1, Raster2-MasterFlat1, Raster3-MasterFlat1, Raster4-MasterFlat1, etc.
    – Alexander
    Feb 27, 2017 at 19:42
  • Do you know how to write loops in R? Loop over the raster files, read each one in, subtract your masterflat, save it (or whatever).
    – Spacedman
    Feb 27, 2017 at 20:42
  • That's exactly what I am having issues with actually - is writing the loop for it. I haven't had much experience with loops for loading files in within a directory and assigning each a unique object.... quite tricky! haha
    – Alexander
    Feb 27, 2017 at 23:31
  • something like allrasters = lapply(list.files(), function(f){raster(f)}) or a for loop...
    – Spacedman
    Feb 27, 2017 at 23:44

1 Answer 1


You seem to want to do something like this:

lightrastdat<- list.files()
corrected_rasters = lapply(
     r = raster(file)
     return(r - masterdark)

# this is how you do mean(r[[1]], r[[2]], r[[3]],... etc) when you don't 
# know how many rasters are in your list:

corrected_mean = do.call(mean, corrected_rasters)

Then save corrected_mean as a raster file.

The lapply gets the file names and for each one applies a function that reads in a raster from that file and subtracts the correction. The end result of lapply here is a list of raster objects.

To compute the mean of a list of objects, you need to use do.call, which applies a function as if the second argument to do.call was in the arguments. This lets you do foo(a[[1]],a[[2]],a[[3]],...) up to however many things are in a.

  • Thanks Spacedman- looks like this does just what I was wanting to do. And looks like I learned a thing or two about the lapply function and do.call - which are definitely extremely valuable. I should be able to adapt these into some other variations of scripts I have in mind. Thanks so much!
    – Alexander
    Mar 2, 2017 at 3:07

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.