在 for 循环中使用 st_write 导出多个形状文件

Using st_write in a for loop to export multiple shape files

我正在尝试根据 FIREYEAR 中的唯一字段值创建多个形状文件(和数据帧)。我已经能够根据每一年的正确数量的观察结果生成单独的数据框。使用 st_write 创建 shapefile 时,尽管它们出现错误。我的代码创建了具有正确名称的单个 shapefile,但每个 shapefile 都包含每年的所有值。在这种情况下,每个导出的 shapefile 应该有 2 个观察结果,但结果是 4 个。2 个来自 1985 年,2 个来自 1986 年。如何在我的 for 循环中实现 st_write 以正确导出多个形状文件?谢谢

示例数据

df1 <- data.frame(FIRENAME = c("Gold", "Tree", "Tank", "Green_1"),
                  UNIQFIREID = c("1985-AZASF-000285", "1985-AZASF-000286", "1985-AZASF-000287", "1985-AZASF-000288"),
                  FIREYEAR = c("1985", "1985", "1986", "1986"),
                  TOTALACRES = c(60, 70, 80, 90))

# I left out the geometry which was sfc_MULTIPOLYGONs and didn't seem to make a difference for the example.

For 循环和 st_write 代码

for(i in unique(df1$FIREYEAR)) {
  list_data <- split(df1, df1$FIREYEAR)
  names(list_data) <- paste0("df_", names(list_data))
  list2env(list_data, .GlobalEnv)
  st_write(df1, dsn = "F:/School/NAU/Forestry/Masters/MSF_Project_2-7-2020/Michaels_Analysis/Fire_History/R", paste0(i), driver = "ESRI Shapefile", append = TRUE)
}

您可能想使用 purrr 包中的 iwalk() 函数,而不是使用 for() 循环。下面的代码将让您知道如何使用它来保存您的文件:

library(sf)
library(purrr)

df1 <- data.frame(FIRENAME = c("Gold", "Tree", "Tank", "Green_1"),
                  UNIQFIREID = c("1985-AZASF-000285", "1985-AZASF-000286", "1985-AZASF-000287", "1985-AZASF-000288"),
                  FIREYEAR = c("1985", "1985", "1986", "1986"),
                  TOTALACRES = c(60, 70, 80, 90))

list_data <- split(df1, df1$FIREYEAR)
names(list_data) <- paste0("df_", names(list_data))

iwalk(list_data, function(dat, name){
  st_write(obj = dat, dsn = paste0("path/to/file/", name, ".shp"))
})

这段代码的问题:

for(i in unique(df1$FIREYEAR)) {
  list_data <- split(df1, df1$FIREYEAR)
  names(list_data) <- paste0("df_", names(list_data))
  list2env(list_data, .GlobalEnv)
  st_write(df1, dsn = "F:/School/NAU/Forestry/Masters/MSF_Project_2-7-2020/Michaels_Analysis/Fire_History/R", paste0(i), driver = "ESRI Shapefile", append = TRUE)
}

是无论你在这个循环中做什么,行:

st_write(df1, dsn = "....

只会一遍又一遍地写df1

要么遍历唯一值并对数据帧进行子集化,只写入子集,就像这样(未经测试,因为目前正在进行升级......但我认为它有效):

## loop over all unique fire years:
for(year in unique(df1$FIREYEAR)) {
## subset only that year's data. 
  df.year = df1[df1$FIREYEAR==year,]
## construct a file name like df_1986.shp and save this data:
  file.name = paste0("df_",year,".shp")
  st_write(df.year, file.name)
}

或使用 split 并循环返回列表的元素。

你不需要无关的包来做这样简单的事情。