读入一个shapefile列表,并在R中对它们进行行绑定(最好使用整洁的语法和sf)

kxe2p93d  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(127)

我有一个目录,里面有50个城市的一堆shapefile(还会积累更多)。它们被分为三组:城市的行政边界(CityA_CD.shp、CityB_CD.shp等)、社区(CityA_Neighborhoods.shp、CityB_Neighborhoods.shp等)和人口普查区块(CityA_blocks.shp、CityB_blocks.shp等)。它们使用公共文件命名语法,具有相同的属性变量集,并且都在相同的CRS中。(我使用QGIS将它们全部转换为这样。)我需要编写每组文件的列表(政治边界,邻域,块)读取为sf对象,然后绑定行为每个组创建一个大的sf对象。然而,我在R中开发此工作流时遇到了一致的问题。

library(tidyverse)
library(sf)
library(mapedit)

# This first line succeeds in creating a character string of the files that match the regex pattern.
filenames <- list.files("Directory", pattern=".*_CDs.*shp", full.names=TRUE)

# This second line creates a list object from the files.
shapefile_list <- lapply(filenames, st_read)

# This third line (adopted from https://github.com/r-spatial/sf/issues/798) fails as follows.
districts <- mapedit:::combine_list_of_sf(shapefile_list)
Error: Column `District_I` cant be converted from character to numeric

# This fourth line fails in an apparently different way (also adopted from https://github.com/r-spatial/sf/issues/798).
districts <- do.call(what = sf:::rbind.sf, args = shapefile_list)
Error in CPL_get_z_range(obj, 2) : z error - expecting three columns;

第一个错误似乎表明我的一个shapefile对于公共变量District_I有一个不正确的变量类,但是R没有提供任何信息来提示我是哪个文件导致了这个错误。
第二个错误似乎是查找z坐标,但在geometry属性中只找到x和y。
在这方面,我有四个问题:
1.我怎样才能让R识别出它试图读取和绑定的列表项是哪个项导致了中止进程的错误呢?
1.我怎样才能迫使R忽略不兼容问题,并强制变量class为character,以便我可以处理R中的变量不一致(如果是这样的话)?
1.如何从导致错误的读取sf对象中完全删除变量(例如,对于进程中的所有read_sf调用,忽略District_I)?
1.更一般地说,这是怎么回事,我如何解决第二个错误?
谢谢你一如既往的帮助。
附言:我知道这篇文章不能以理想的方式“复制”,但除了复制我所有shapefile的内容外,我不知道如何做到这一点。如果我在这一点上错了,我很乐意接受这方面的任何智慧。
更新:我已运行

filenames <- list.files("Directory", pattern=".*_CDs.*shp", full.names=TRUE)
shapefile_list <- lapply(filenames, st_read)
districts <- mapedit:::combine_list_of_sf(shapefile_list)

成功地在三个shapefile的子集上运行。因此,我已经确认其中一个文件中的列District_I之间存在某种类冲突,导致在整个批处理上运行代码时出现停顿。但是,我需要错误来识别导致问题的文件名,以便在文件中修复它,或者需要代码来强制所有文件中的District_I为字符(这是我希望变量所在的类)。
一个便条,特别是关于巴勃罗的建议:

districts <- do.call(what = dplyr::rbind_all, shapefile_list)

导致错误Error in (function (x, id = NULL) : unused argument
后面跟着一长串数字和坐标。
mapedit:::combine_list_of_sf(shapefile_list)
确实是从列表中读取并合并文件的机制,但我仍然需要一种方法来诊断shapefile中列不兼容错误的来源。

kmpatx3s

kmpatx3s1#

因此,在经历了许多烦恼和巴勃罗的一些伟大指导(以及他到https://community.rstudio.com/t/simplest-way-to-modify-the-same-column-in-multiple-dataframes-in-a-list/13076的链接)之后,下面的工作:

library(tidyverse)
library(sf)

# Reads in all shapefiles from Directory that include the string "_CDs".
filenames <- list.files("Directory", pattern=".*_CDs.*shp", full.names=TRUE)

# Applies the function st_read from the sf package to each file saved as a character string to transform the file list to a list object.
shapefile_list <- lapply(filenames, st_read)

# Creates a function that transforms a problem variable to class character for all shapefile reads.
my_func <- function(data, my_col){
  my_col <- enexpr(my_col)

  output <- data %>% 
    mutate(!!my_col := as.character(!!my_col))
}

# Applies the new function to our list of shapefiles and specifies "District_I" as our problem variable.
districts <- map_dfr(shapefile_list, ~my_func(.x, District_I))

相关问题