terra icon indicating copy to clipboard operation
terra copied to clipboard

set.values assigns to all layers

Open Jean-Romain opened this issue 3 years ago • 1 comments

set.values() assigns to all layers without being able to modify a specific layer

library(terra)
s <- rast(ncols=5, nrows=5, nlyrs=3)
set.values(s, 1:10, runif(10))
plot(s)

The only way I can find to touch a layer is

s[[2]][cells] <- value

Which involves a complex call stack and deeps copies. When touching multiple layers the code becomes extremely slow.

I think that providing a way to assign values to cells per layer would be useful.

Thanks

Jean-Romain avatar Feb 08 '22 13:02 Jean-Romain

You can do

library(terra)
s <- rast(ncols=5, nrows=5, nlyrs=3)
set.values(s, 1:10, runif(10))

# replace an entire layer
s[[2]] = s[[3]] / s[[1]]
# replace cells
s[[1:2]][4] = 8

That seems to work OK. I suppose it becomes slow with large objects, as they may be read from disk, and written to temp files. In those situations, this kind of interactive use is less well supported. It would be possible to update existing files but that has its own risks; and I am wary of it. And if things work for a single layer, you can always operate on that layer, and re-insert it into the object. Perhaps an in place set.layer(x, i, y) (update layer i in x with y could help?

rhijmans avatar Apr 06 '22 03:04 rhijmans

You can now do things like

library(terra)
s <- rast(ncols=5, nrows=5, nlyrs=3)
set.values(s, 1:10, runif(10), layer=2)

set.values(s, 11:20, cbind(1, runif(10)), layer=2:3)

rhijmans avatar Sep 19 '22 19:09 rhijmans

A future refinement could be to not force all values (of the data sources changed) to memory by (optionally) allowing to update values on (temporary?) files, or else by creating temporary files where necessary.

rhijmans avatar Sep 19 '22 19:09 rhijmans

It is now also possible to use a third index, k, to reference the layer when replacing or subsetting a SpatRaster with [ and [<-

library(terra)
s <- rast(ncols=5, nrows=5, nlyrs=3)
set.values(s, 1:10, 1:10)

s[3, 3, 3] <- 100
s[20, k=1:2] <- 18
s[cbind(4,4,3)] <- 50

s[3, 3, 3] 

rhijmans avatar Sep 27 '22 03:09 rhijmans