将for循环嵌套到R代码中以减少冗余

将for循环嵌套到R代码中以减少冗余,r,for-loop,R,For Loop,编辑:光栅是从国家气象局获得的()。我的郡形文件是肯塔基州的,可以从Esri的ArcGIS在线数据服务中获得 我有5个光栅,其中包含不同记录时期的降水数据:每日、前30天、60天、90天和365天。我想执行分区统计,以计算位于表示县边界多边形的形状文件中的每个光栅的平均值。我有120个多边形 我有可以工作的代码,但我想改进它。目前,它需要大量复制和粘贴相同的代码 library(rgdal) library(raster) library(sf) library(maptools) # Cou

编辑:光栅是从国家气象局获得的()。我的郡形文件是肯塔基州的,可以从Esri的ArcGIS在线数据服务中获得

我有5个光栅,其中包含不同记录时期的降水数据:每日、前30天、60天、90天和365天。我想执行分区统计,以计算位于表示县边界多边形的形状文件中的每个光栅的平均值。我有120个多边形

我有可以工作的代码,但我想改进它。目前,它需要大量复制和粘贴相同的代码

library(rgdal)
library(raster)
library(sf)
library(maptools)

# County shapefiles
input_path <- "C:/path/to/shapefiles/GIS_data/Counties"
files <- list.files(input_path, pattern="[.]shp$", full.names=TRUE)
allShapes <- lapply(files, readOGR)
filenames <- list.files(input_path, pattern="[.]shp$")

# Rasters
NWS1_daily <- raster(paste(daily_downloads, daily_fname, sep='/'), band = 1)
NWS1_prev30 <- raster(paste(bulk_downloads, prev30_fname, sep='/'), band = 1)
NWS1_prev90 <- raster(paste(bulk_downloads, prev90_fname, sep='/'), band = 1)
NWS1_prev120 <- raster(paste(bulk_downloads, prev120_fname, sep='/'), band = 1)
NWS1_prev365 <- raster(paste(bulk_downloads, prev365_fname, sep='/'), band = 1)

# Perform zonal statistics to acquire mean observation for each county
observations <- vector()
filenames <- vector()
for (i in 1:length(allShapes)){
  observations[i] <- c(extract(NWS1_daily, allShapes[[i]], fun=mean, na.rm=TRUE, weights=T, normalizeWeights=F))
  filenames<-files[i]
}
filenames <- list.files(input_path, pattern="[.]shp$") 
observations<-data.frame(observations,filenames,stringsAsFactors=FALSE)

observations <- vector()
filenames <- vector()
for (i in 1:length(allShapes)){
  observations[i] <- c(extract(NWS1_prev30, allShapes[[i]], fun=mean, na.rm=TRUE, weights=T, normalizeWeights=F))
  filenames<-files[i]
}
filenames <- list.files(input_path, pattern="[.]shp$") 
observations<-data.frame(observations,filenames,stringsAsFactors=FALSE)

observations <- vector()
filenames <- vector()
for (i in 1:length(allShapes)){
  observations[i] <- c(extract(NWS1_prev90, allShapes[[i]], fun=mean, na.rm=TRUE, weights=T, normalizeWeights=F))
  filenames<-files[i]
}
filenames <- list.files(input_path, pattern="[.]shp$") 
observations<-data.frame(observations,filenames,stringsAsFactors=FALSE)

observations <- vector()
filenames <- vector()
for (i in 1:length(allShapes)){
  observations[i] <- c(extract(NWS1_prev120, allShapes[[i]], fun=mean, na.rm=TRUE, weights=T, normalizeWeights=F))
  filenames<-files[i]
}
filenames <- list.files(input_path, pattern="[.]shp$") 
observations<-data.frame(observations,filenames,stringsAsFactors=FALSE)

observations <- vector()
filenames <- vector()
for (i in 1:length(allShapes)){
  observations[i] <- c(extract(NWS1_prev365, allShapes[[i]], fun=mean, na.rm=TRUE, weights=T, normalizeWeights=F))
  filenames<-files[i]
}
filenames <- list.files(input_path, pattern="[.]shp$") 
observations<-data.frame(observations,filenames,stringsAsFactors=FALSE)


库(rgdal)
图书馆(光栅)
图书馆(sf)
图书馆(地图工具)
#郡形文件
输入路径因为(的返回)是特殊的S4类对象,所以将它们与
c()绑定在一起,如
c(NWS1_daily,NWS1_prev30,NWS1_prev90,NWS1_prev120,NWS1_prev365)
可能不会生成五个对象的列表,但可能会生成一个不同维度的简化数组。使用
str(光栅名称\u波段1)
检查此对象。对于复杂对象,请使用
list()
在集合中绑定在一起

另外,代替嵌套<代码> 循环需要初始化对象并分配给它们的簿记,考虑嵌套的应用族方法。具体地说,运行

lappy
在光栅对象上迭代,运行嵌套
sapply
在所有形状上迭代,为in
data.frame
调用构建观察值。由于所有文件名都相同,请将其作为全局对象分配一次。甚至使用
setNames
包装调用以呈现命名列表

# LIST OF RASTER OBJECTS (USE list() NOT c())
raster_list <- list(NWS1_daily, NWS1_prev30, NWS1_prev90, NWS1_prev120, NWS1_prev365)
filenames <- list.files(input_path, pattern="[.]shp$"))

# USER-DEFINED FUNCTION
df_build <- function(obj_raster) {
   observations <- sapply(allShapes, function(s) 
                               c(extract(obj_raster, s, fun=mean, na.rm=TRUE, 
                                         weights=TRUE, normalizeWeights=FALSE))
                          )
   data.frame(observations, filenames, stringsAsFactors=FALSE)
} 

# BUILD NAMED LIST OF DFs
df_list <- setNames(lapply(raster_list, df_build),
                    c("NWS1_daily", "NWS1_prev30", "NWS1_prev90", 
                      "NWS1_prev120", "NWS1_prev365")
                   )

# DF OUTPUTS
df_list$NWS1_daily
df_list$NWS1_prev30
df_list$NWS1_prev90
...

注意:以上代码未经测试,可能需要根据全局对象进行各种调整。

从哪个包中提取?在
tidyr
中,它会分解列,但在
magrittr
中,它只是
[
。抱歉-摘录来自光栅软件包。如果你能找到一种方法让示例使用公开可用的数据,这样我们就可以运行代码,这将是一个巨大的帮助。好主意。我更新了这篇文章,如果人们想使用它,可以在哪里获取数据。你为什么重复
文件名
# LIST OF RASTER OBJECTS (USE list() NOT c())
raster_list <- list(NWS1_daily, NWS1_prev30, NWS1_prev90, NWS1_prev120, NWS1_prev365)
filenames <- list.files(input_path, pattern="[.]shp$"))

# USER-DEFINED FUNCTION
df_build <- function(obj_raster) {
   observations <- sapply(allShapes, function(s) 
                               c(extract(obj_raster, s, fun=mean, na.rm=TRUE, 
                                         weights=TRUE, normalizeWeights=FALSE))
                          )
   data.frame(observations, filenames, stringsAsFactors=FALSE)
} 

# BUILD NAMED LIST OF DFs
df_list <- setNames(lapply(raster_list, df_build),
                    c("NWS1_daily", "NWS1_prev30", "NWS1_prev90", 
                      "NWS1_prev120", "NWS1_prev365")
                   )

# DF OUTPUTS
df_list$NWS1_daily
df_list$NWS1_prev30
df_list$NWS1_prev90
...
raster_names <- c("NWS1_daily", "NWS1_prev30", "NWS1_prev90",
                  "NWS1_prev120", "NWS1_prev365")
filenames <- list.files(input_path, pattern="[.]shp$"))

df_build <- function(raster_nm) {
   # keep all same but change: extract(obj_raster, s, ... --> extract(get(raster_nm), s, ...
}

# BUILD NAMED LIST OF DFs
df_list <- sapply(raster_names, df_build, simplify = FALSE)