Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
601 views
in Technique[技术] by (71.8m points)

gis - Assign one of three values at random to a raster cell given constraints

I'm working on some post processing of a very large raster (437760000 cells) using other raster layers of the same extent/crs for constraints. The code is working for the most part but I'm running into an issue.

r1[r2== 6 & r3>= 40 & r3<= 60] <- sample(2:4, length(r1[r2== 6 & r3>= 40 & r3 <= 60]), replace = T)

Where r1, r2, and r3 are unique raster layers. r1 is being updated based on the constraints with the aim to improve the map.

This code executes with no issues but throws the following warning upon completion:

Warning message:
In .local(x, i, j = j, ..., value) :
  the first replacement value is used for all cells

I want to ensure that all three values are being picked at random (and eventually I want to use the prob argument in sample to weight one of the values). I've tried numerous fixes and they all throw the same warning message, which I'm taking to mean that only one of the three values is being applied across the raster. I am working in terra for this.

Any thoughts? Thanks!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is a reproducible example for your problem:

library(terra)

set.seed(123)
r1 <- rast(matrix(round(runif(400, 0, 100)), 20, 20))
plot(r1)

r2 <- rast(matrix(round(runif(400, 0, 10)), 20, 20))
r3 <- rast(matrix(round(runif(400, 30, 70)), 20, 20))

Even if I wasn't able to reproduce your warning code, I think your problem is in your interpretation of this call: r2== 6 & r3>= 40 & r3 <= 60. This line produces a raster:

r2== 6 & r3>= 40 & r3 <= 60
class       : SpatRaster 
dimensions  : 20, 20, 1  (nrow, ncol, nlyr)
resolution  : 0.05, 0.05  (x, y)
extent      : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
coord. ref. :  
source      : memory 
name        : lyr.1 
min value   :     0 
max value   :     1 

An therefore making this call r1[r2== 6 & r3>= 40 & r3 <= 60] produce a dataframe:

str(r1[r2== 6 & r3>= 40 & r3 <= 60])
'data.frame':   17 obs. of  1 variable:
 $ lyr.1: num  2 2 2 2 2 2 2 2 2 2 ...

You don't want that because length of a 1 column data.frame = 1 and because you can't do value substitution with a data.frame.

Try this instead:

pixel_to_change <- values(r2== 6 & r3>= 40 & r3<= 60) == 1
r1[pixel_to_change] <- sample(2:4, sum(pixel_to_change), replace = T)  

It may be what your are looking for.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...