Прочтите список шейп-файлов и привяжите их в R (желательно с использованием аккуратного синтаксиса и sf)
У меня есть каталог с кучей шейп-файлов для 50 городов (и их накопится еще). Они делятся на три группы: политические границы городов (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;
Первая ошибка, похоже, указывает на то, что в одном из моих шейп-файлов указан неправильный класс переменной для общей переменной. District_I
но R не предоставляет информации, чтобы понять, какой файл вызывает ошибку.
Вторая ошибка, похоже, ищет координату z, но находит только x и y в атрибуте геометрии.
У меня четыре вопроса по этому поводу:
- Как я могу заставить R определить, какой элемент списка он пытается прочитать, а привязка вызывает ошибку, останавливающую процесс?
- Как я могу заставить R игнорировать проблему несовместимости и принуждать класс переменных к символу, чтобы я мог справиться с несогласованностью переменных (если это так) в R?
- Как я могу полностью удалить переменную из прочитанных объектов sf, вызывающих ошибку (т.е. опустить
District_I
для всехread_sf
звонки в процессе)? - В общем, что происходит и как я могу решить вторую ошибку?
Всем как всегда спасибо за помощь.
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 ответ
Итак, после долгих переживаний и отличных указаний Пабло (и его ссылки на 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))