I have a raster stack that has NULL values from applying a focal buffer. They're not NA values but 0. Each layer shares the same extent, but the layers with the larger buffer widths have more 0 values (more whitespace around the perimeter) than those with smaller buffer widths. How can I create a new stack that clips each layer based on the extent of the largest buffer layer after removing these 0 values? In other words, I would like the extent of each layer to match the smallest extent after removing 0 values. In the example below, the X2017.10.10.arterial10000m layer would have the smallest extent.

enter image description here

  • 1
    Do zeroes occur elsewhere in the layers, or are they only ever present as a border of zeroes round your data? Because its a lot easier to eventually construct a mask if you know there's no zeroes anywhere else except the border. Unless R has a "greedy crop" function that can trim the edges of rasters.... Let's go read some documentation... – Spacedman Dec 20 '18 at 8:14
  • Yes, I've realized that some of the layers have zeroes within the actual data (and not just outside the desired extent). For now, I'm working on cropping using a new layer that has the correct extent. I think I'm onto something! Thanks for looking into this. – philiporlando Dec 20 '18 at 8:17
  • 1
    Okay, I'm thinking of the raster "trim" function. I think if you trim all your layers then crop by the smallest resulting layer, or crop by all of them because the smallest will "win".... – Spacedman Dec 20 '18 at 8:22

For some raster stack with white (zero) borders, s:

> plot(s)

enter image description here

Note the first layer has no border, the second a wide border, and the third a narrow one-pixel border.

Construct a list of trimmed layers, mm - note this is not a stack because the extents are now different:

> mm = lapply(unstack(s),trim,values=0)

Make a copy of s:

> ss = s

And now crop it to each of the masks. The smallest mask wins:

> for(i in 1:length(mm)){ss = crop(ss, mm[[i]])}
> plot(ss)

enter image description here

Note the layers all look the same because I created them from the same random matrix.

Instead of cropping with all the layers it should suffice to just find the layer with the smallest extent and crop by that one only.

  • This is working with my data too. Does it make sense that the extent of ss is the same as s? – philiporlando Dec 20 '18 at 8:55
  • 1
    no, because it should have trimmed it. For my test, extent(s) is 0,1,0,1 and extent(ss) is 0.125,.875,.1666,.8333 – Spacedman Dec 20 '18 at 9:17
  • Strange, I'm still getting the same extent with my data. The plotted output of each of my layers looks correct, but the extent has not changed. – philiporlando Dec 23 '18 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.