R语言 使用循环创建对象,然后应用函数

rvpgvaaj  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(209)

我试图通过使用函数和for循环来缩短代码。
对于下面的例子,我想创建5个不同的对象,然后将raster应用到每个创建的对象上。我如何使用循环和函数来实现这一点呢?

#Defining variables of interest
url = "https://files.isric.org/soilgrids/latest/data/" # Path to the webDAV data.
voi1 = "sand"
voi2 = "clay"
voi3 = "silt"
voi4 = "phh2o"
voi5 = "soc"
depth = "5-15cm"

quantile = "mean" # prediction uncertainty quantified by probability distribution. Using mean of distribution
voi_layer1 = paste(paste(paste(url, voi1, "/", voi1, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer2 = paste(paste(paste(url, voi2, "/", voi2, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer3 = paste(paste(paste(url, voi3, "/", voi3, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer4 = paste(paste(paste(url, voi4, "/", voi4, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer5 = paste(paste(paste(url, voi5, "/", voi5, sep=""), depth, quantile, sep="_"), '.vrt', sep="")

#Apply 'raster' so can derive descriptions of each layer
sand = raster(voi_layer1)
clay = raster(voi_layer2)
silt = raster(voi_layer3)
ph = raster(voi_layer4)
org_carb = raster(voi_layer5)
hxzsmxv2

hxzsmxv21#

有几种方法可以简化代码。由于对每个VOI执行相同的操作,因此可以将它们存储在一个向量中。注意,这里的voi包含所有5个VOI:

base_url <- "https://files.isric.org/soilgrids/latest/data/" # Path to the webDAV data.
voi <- c('sand', 'clay', 'silt', 'phh2o', 'soc')
depth <- "5-15cm"
quantile <- "mean"

我们可以使用sprintf来更简洁地创建fetch URL:

urls <- sprintf('%s%s/%s_%s_%s.vrt', base_url, voi, voi, depth, quantile)
names(urls) <- voi
                                                                       sand 
  "https://files.isric.org/soilgrids/latest/data/sand/sand_5-15cm_mean.vrt" 
                                                                       clay 
  "https://files.isric.org/soilgrids/latest/data/clay/clay_5-15cm_mean.vrt" 
                                                                       silt 
  "https://files.isric.org/soilgrids/latest/data/silt/silt_5-15cm_mean.vrt" 
                                                                      phh2o 
"https://files.isric.org/soilgrids/latest/data/phh2o/phh2o_5-15cm_mean.vrt" 
                                                                        soc 
    "https://files.isric.org/soilgrids/latest/data/soc/soc_5-15cm_mean.vrt"

最后,我们可以使用lapply对每个构造的URL执行raster()函数(lapply是一个循环函数)。

rasters <- lapply(urls, raster)

请注意,由于我们已经为上述urls的元素提供了名称,因此这些名称将保留在rasters结果中,因此您可以使用数字索引(rasters[1])或命名索引(rasters['sand'])来检索各个栅格。

7hiiyaii

7hiiyaii2#

另一个变化

url = "https://files.isric.org/soilgrids/latest/data/"
voi = c("sand", "clay", "silt", "phh2o", "soc")
depth = "5-15cm"
quantile = "mean"

f <- paste0(url, voi, "/", paste(voi, depth, quantile, sep="_"), '.vrt')

“raster”已过时,我们改用“terra”并创建SpatRasterDataset

library(terra)
x <- sds(f)

或SpatRasters列表

y <- lapply(f, rast)

另请参阅geodata::soil_worldgeodata::soil_world_vsi以获取这些数据。

nqwrtyyt

nqwrtyyt3#

一般来说,你可以创建一个函数来创建一个对象,在一个for循环中调用它,然后使用assign来为它们赋值变量名。我推荐使用“glue”包中的glue函数,因为它比paste更直观。我不能让raster函数在我的电脑上工作,因为我得到了this error。然而,这就是我的想法。

library(glue)

raster_object <- function(url, voi, depth, quantile){
  return(raster(glue("{url}/{voi}/{voi}_{depth}_{quantile}.vrt")))
}

for (voi in c("sand", "clay")){
  assign(glue("raster_{voi}"),  raster_object(url = "https://files.isric.org/soilgrids/latest/data", voi, depth = "5-15cm", quantile = "mean"))
}

相关问题