简体   繁体   English

在 R 中的光栅堆栈/砖块上应用复杂的数学函数,并创建两个相互依赖的不同光栅堆栈

[英]Applying complex mathematical functions on Raster Stacks/Bricks in R and creating two different Raster stacks which are dependent on each other

I have a raster brick (ncell=28536 and nlayers=181).我有一个光栅砖(ncell=28536 和 nlayers=181)。 I need to run mathematical functions on the original brick and create two more bricks of same size.我需要在原始积木上运行数学函数并创建另外两块相同大小的积木。 Where both output bricks are dependent on each other.两个 output 块相互依赖的地方。

inputBrick has 181 layers and 28536 cells per layer. inputBrick 有 181 层,每层有 28536 个单元格。 outputBrick1 will calculate values of its 1st layer by analyzing outputBrick2's 1st layer. outputBrick1 将通过分析 outputBrick2 的第一层来计算其第一层的值。 Then outputBrick2 will calculate values of its 2nd layer by analyzing outputBricks1's 1st layer and so on.然后 outputBrick2 将通过分析 outputBricks1 的第一层等来计算其第二层的值。

I created a function that works fine with 24 cells and 181 layers.我创建了一个 function,它可以很好地处理 24 个单元格和 181 个层。 But takes forever for 28000 cells and 181 layers.但是 28000 个单元格和 181 个层需要永远。 I know I shouldn't be using for loops for this but as I'm not a programmer I'm struggling.我知道我不应该为此使用 for 循环,但因为我不是程序员,所以我很挣扎。

Here is some example data for a much smaller dataset.这是一个小得多的数据集的一些示例数据。 There are 3 RasterBricks.有 3 个 RasterBricks。 Input has values while both outputs are empty输入有值,而两个输出均为空

library(raster)
b <- brick(ncols=5, nrows=5, nl=5)
inBrick <- setValues(b, runif(ncell(b) * nlayers(b)))
inBrick[c(1,2,3,22,23,24,25)] <- NA
outBrick1 <- inBrick
outBrick1[] <- NA
outBrick2 <- outBrick1

ini <- 0.3
p <- 0.15
p1 <- p/3
p2 <- p-(p/3)
fc <- 0.3
var1 <- which(!is.na(inBrick[[1]][]))

outBrick2[[1]][var1] <- ini
### now outBrick2 has initial values in 1st layer
weather <- c(0.1, 0, 0, 0, 0.3)

Calculations that I want to do and have no idea how to do it efficiently without using for loops我想做但不知道如何在不使用 for 循环的情况下有效地进行的计算

var3 <- 1:ncell(inBrick)
### outBrick1 Calculations
for (i in 1:nlayers(inBrick)) {
varr1 <- inBrick[[i]][]*(((outBrick2[[i]][]-p1)/(p2))^2)
for (j in 1:ncell(inBrick)) {
if(!is.na(outBrick2[[i]][j])){
  if(outBrick2[[i]][j]>p){
     outBrick1[[i]][j] <- inBrick[[i]][j]
  }else{
     outBrick1[[i]][j] <- varr1[j]
    }
  }
}
###outBrick2 Calculations
for (k in 2:nlayers(inBrick)) {
var2 <- outBrick2[[k-1]][] + (weather[k-1]-outBrick1[[k-1]][])/100
 for(l in 1:ncell(inBrick)){
  var3[l] <- min(fc, var2[l])
 }
 outBrick2[[k]][] <- var3
 }
}

Now, I want to basically understand what the best approach is to deal with situations like this.现在,我想基本上了解处理此类情况的最佳方法是什么。 I tried increasing memory too by following commands我也尝试通过以下命令增加 memory

rasterOptions(maxmemory = 5.17e+10)
rasterOptions(memfrac = 0.8)
rasterOptions(chunksize = 5.17e+10)

but when I see CPU and RAM usage its barely 6% and 10% respectively.但是当我看到 CPU 和 RAM 使用率分别只有 6% 和 10%。 R uses only 5% CPU and 1GB RAM. R 仅使用 5% CPU 和 1GB 内存。 My system has 64GB RAM, 16GB GPU.我的系统有 64GB 内存,16GB GPU。

Here is an attempt.这是一个尝试。 This is much more concise.这样就简洁多了。 It is only three times faster on this example, but the gain may be larger on your real data.在这个例子中它只快了三倍,但在你的真实数据上增益可能更大。

library(terra)
b <- r1 <- r2 <- rast(ncols=5, nrows=5, nl=5, vals=NA)
set.seed(0)
values(b) <- runif(size(b))
b[c(1,2,3,22,23,24,25)] <- NA

p  <- 0.15
p1 <- p/3
p2 <- p-(p/3)
fc <- 0.3
weather <- c(0.1, 0, 0, 0, 0.3)

r2[[1]] <- ifel(is.na(b[[1]]), NA, 0.3)

for (i in 1:nlyr(b)) {
    varr1 <- b[[i]] * (((r2[[i]] - p1)/p2)^2)
    r1[[i]] <- ifel(r2[[i]] > p, b[[i]], varr1)
    for (k in 2:nlyr(b)) {
        r2[[k]] <- min(r2[[k-1]] + (weather[k-1] - r1[[k-1]]) /100, fc)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM