【问题标题】:R loop to perform the same task on multiple Rasters?R循环在多个栅格上执行相同的任务?
【发布时间】:2021-08-03 16:30:38
【问题描述】:

我希望创建一个循环来对文件夹中的 12 个栅格执行相同的任务,我已经为 1 个栅格完成了上述任务。该任务涉及计数单元格(具有 1 2 3 或 4 类),然后计算每个类的面积。然后我需要将面积值保存在一个新的数据框中,以便进一步分析和可视化。

我需要将 1 个栅格保存为基线(这是我的示例中的那个),其余的标题为 Sub_A、Sub_B 等等,直到 Sub_K。

library(sp)
library(raster)
library(rgdal)
library(leaflet)

wd<- ('E:/Subs')
setwd(wd)


zuk1<- raster("E:/Subs/ZUK1_MAX.tif")
zuk1
zuk1<- setMinMax(zuk1)
zuk1[zuk1 == 0]<- NA

plot(zuk1, main='Baseline Hazard')

#count for pixel per class
hazard_fr<- freq(zuk1, useNA="no")
hazard_fr
resclass<- res(zuk1)
area_km2<- hazard_fr[,"count"] * prod(resclass) * 1e-06
df_class_area<- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))
df_class_area

【问题讨论】:

    标签: r raster rgdal


    【解决方案1】:

    这是获得所需输出的另一种方法。这与杰里米的回答非常相似;但使用lapply

    # List files which names start with zuk and end with .tif
    zuk_files <- list.files(pattern = glob2rx("zuk*.tif"))
    
    # The loop
    resuls <- lapply(zuk_files, function(x){
      zuk1 <- raster(x)
      zuk1 <- setMinMax(zuk1)
      zuk1[zuk1 == 0] <- NA
      hazard_fr <- freq(zuk1, useNA="no")
      resclass <- res(zuk1)
      hazard_fr[,"count"] * prod(resclass) * 1e-06
    })
    

    【讨论】:

    • zuk1 &lt;- setMinMax(zuk1) 可以省略;而zuk1[zuk1 == 0] &lt;- NA 最好写成zuk1 &lt;- reclassify(zuk1, cbind(0, NA))
    【解决方案2】:

    如果您提供一个小的示例数据,其他人会更容易帮助您。我知道在这种情况下,您可能无法提供它们,因为 tiff 文件通常很大。

    不管怎样,你可以试试这个:

    # list all tiff files in your directory 
    zuk_files <- list.files(pattern = "*.tif")  
    
    # you can also try to be more specific like:
     zuk_files <- list.files(pattern = "ZUK.*_MAX.tif")  
    
    # then apply the same operations for all of the target files
    
    # first create a list for whatever you want to loop over
    zuk <- list()
    hazard_fr <- list()
    resclass <- list()
    area_km2 <- list()
    df_class_area <- list()
    
    # now do the same things for all items in the list
    for (i in 1:length(zuk_files)){
      zuk[[i]] <- raster(zuk_files[[i]])
      zuk[[i]] <- setMinMax(zuk[[i]])
      zuk[[i]][zuk[[i]] == 0] <- NA
      hazard_fr[[i]] <- freq(zuk[[i]],useNA="no")
      resclass[[i]] <- res(zuk[[i]])
      area_km2[[i]] <- hazard_fr[[i]][,"count"] * prod(resclass[[i]]) * 1e-06
      df_class_area[[i]] <- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))
    }
    
    # then all the data are stored in the list, you can acess them using the index like:
    zuk[[1]]
    
    # or save out your target results like:
    zuk_1 <- zuk[[1]]
    

    但我不确定你是否犯了错误

    df_class_area <- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))
    

    我不确定这条线是否符合您的期望,无论如何,您可以从上面的示例中学习为该 df_class_area 编写循环,我相信。

    【讨论】:

    • 谢谢你,是的,我的 tif 文件非常大,但它们都具有相同的范围、投影等。
    • 在尝试上述代码时,即使在循环之后列表也是空的。
    • @AmrieSingh 我不知道是什么导致了这个问题,但调试的一般做法是逐行运行代码。在 for 循环中,首先尝试只包含一个操作,例如 ``zuk[[i]]
    • 您好,这不是错误,只是 R 花了一些时间来处理我的数据,因为它们太大了。现在唯一的问题是它没有从所有栅格中删除空值。
    猜你喜欢
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2014-03-01
    • 2021-11-12
    • 2020-05-10
    相关资源
    最近更新 更多