I have a RasterStack object and want to replace some values at a set of indices in all layers. That doesn't work as expected, however. setValues replaces all values even though I pass a set of indices. The following code illustrates my problem:

library (raster)

# Create sample object
r1 <- raster (nrows = 10, ncols = 10)
r2 <- raster (nrows = 10, ncols = 10)
r3 <- raster (nrows = 10, ncols = 10)
values (r1) <- runif (ncell (r1))
values (r2) <- runif (ncell (r2))
values (r3) <- runif (ncell (r3))
rst <- stack (r1, r2, r3)

# Pixel IDs to replace
indexvalues <- c (1, 2, 99)

# Values to substitute
newvalues <- c (10, -10, NA)

result <- setValues (rst, newvalues, index = indexvalues)

# All values are replaced, not just the ones at the indices
plot (result)

### This is what I would expect
values (r1) [indexvalues] <- newvalues
values (r2) [indexvalues] <- newvalues
values (r3) [indexvalues] <- newvalues
rst <- stack (r1, r2, r3)

plot (rst)

Any ideas how I can get setValues to produce my expected result or is there something else wrong? Thanks!

  • 1
    The index parameter is only valid if rst is a RasterLayerSparse class object. What's wrong with your values(r1)[index]<-values method? I suspect the index parameter for RasterLayerSparse objects exists because direct value replacement might not work for sparse rasters. They're a rare thing.... – Spacedman Dec 2 '20 at 16:48
  • Thank you, that clears it up! There's nothing wrong with values(r1)[index]<-values per se, it's just a bit cumbersome when dealing with a lot of layers and I thought I could do a one liner instead. – karpfen Dec 2 '20 at 16:59
  • It would be more efficient, and clearer, to do r1[index] <- values – Robert Hijmans Dec 3 '20 at 3:24

The values of a stack is a matrix, so you can directly replace rows to change all the pixels in a location in a stack without having to do each layer separately:

Test stack, using fixed values per layer to make it easier to see the changes than random numbers:

> r1 = raster(matrix(50,10,10))
> r2 = raster(matrix(60,10,10))
> r3 = raster(matrix(70,10,10))
> rst <- stack (r1, r2, r3)
> plot(rst)

Then replace values by row:

> values(rst)[indexvalues,] =  newvalues
> plot(rst)

enter image description here

  • 1
    Do you even need values? Cant you just use the brackets rst[indexvalues] <- newvalues or for a specific layer rst[[1]][indexvalues] <- newvalues – Jeffrey Evans Dec 2 '20 at 17:09
  • I think values() is safer when you have rasters that are loaded-on-demand.... – Spacedman Dec 2 '20 at 21:42
  • FWIW: I agree with Jeffrey. rst[i] <- v is more direct, as intended, and could be memory safe. – Robert Hijmans Dec 3 '20 at 3:15

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.