Прочтите список шейп-файлов и привяжите их по строке в R (желательно с использованием аккуратного синтаксиса и sf) - PullRequest
0 голосов
/ 17 июня 2020

У меня есть каталог с кучей шейп-файлов для 50 городов (и накопится еще). Они разделены на три группы: политические границы городов (CityA_CD.shp, CityB_CD.shp, et c.), Кварталы (CityA_Neighborhoods.shp, CityB_Neighborhoods.shp, et c.) И кварталы переписи (CityA_blocks. shp, CityB_blocks.shp и др. c.). Они используют общий синтаксис именования файлов, имеют одинаковый набор переменных атрибутов и все находятся в одной 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;

Первая ошибка, похоже, указывает на то, что один из моих шейп-файлов имеет неправильный класс переменной для общей переменной District_I, но R не предоставляет информацию, чтобы понять, какой файл вызывает ошибку.

Вторая ошибка, похоже, ищет координату z, но находит только x и y в атрибуте геометрии.

У меня четыре вопроса на этом фронте:

  1. Как я могу заставить R определить, какой элемент списка он пытается прочитать и привязать вызывает ошибку, останавливающую процесс?
  2. Как я могу заставить R выполнить игнорировать проблему несовместимости и принуждать класс переменной к символу, чтобы я мог справиться с несогласованностью переменных (если это так) в R?
  3. Как я могу полностью удалить переменную из прочитанных объектов sf, которые вызывая ошибку (т.е. опускать District_I для всех read_sf вызовов в процессе)?
  4. В общем, что происходит и как я могу решить вторую ошибку?

Спасибо всем, как всегда, за вашу помощь.

PS: Я знаю, что этот пост нельзя "воспроизвести" желаемым образом, но Я не знаю, как это сделать, кроме копирования содержимого всех моих шейп-файлов. Если я ошибаюсь в этом пункте, я с радостью приму любую мудрость на этом фронте.

ОБНОВЛЕНИЕ: Я успешно выполнил

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

на подмножестве из трех шейп-файлов . Итак, я подтвердил, что существует конфликт классов между столбцом 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)

определенно является механизмом для чтения из списка и объединения файлов, но мне все еще нужен способ диагностировать источник ошибки несовместимости столбцов в шейп-файлах.

1 Ответ

0 голосов
/ 19 июня 2020

Итак, после долгих волнений и отличного руководства от Пабло (и его ссылки на 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...