0

我有一个包含 50 个城市的 shapefile 的目录(并且会积累更多)。它们分为三组:城市的政治边界(CityA_CD.shp、CityB_CD.shp 等)、社区(CityA_Neighborhoods.shp、CityB_Neighborhoods.shp 等)和人口普查街区(CityA_blocks.shp、CityB_blocks.shp、 ETC。)。它们使用通用的文件命名语法,具有相同的属性变量集,并且都在同一个 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 没有提供任何信息来提示我是哪个文件导致了错误。

第二个错误似乎是在寻找 az 坐标,但只在几何属性中找到 x 和 y。

在这方面我有四个问题:

  1. 我怎样才能让 R 识别它正在尝试读取和绑定的列表项导致停止进程的错误?
  2. 如何强制 R 忽略不兼容问题并将变量类强制转换为字符,以便我可以处理 R 中的变量不一致(如果是这样的话)?
  3. 如何从导致错误的读取 sf 对象中完全删除变量(即忽略进程中District_I的所有read_sf调用)?
  4. 更一般地说,发生了什么,我该如何解决第二个错误?

一如既往地感谢大家的帮助。

PS:我知道这篇文章不能以期望的方式“重现”,但除了复制我所有 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所有文件中的字符(这是我希望该变量存在的类)。

一个注释,特别是关于 Pablo 的建议:

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 的列不兼容错误的来源。

4

1 回答 1

0

因此,经过 Pablo 的大量烦恼和一些很好的指导(以及他对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))
于 2020-06-19T01:11:16.323 回答