Преобразование фрейма данных, содержащего координаты полигонов, в sf

Я новичок в пакете sf, и у меня возникли трудности с преобразованием моего фрейма данных в объект sf.

У меня есть фрейм данных, содержащий координаты полигонов в каждой строке. Эти координаты находятся в одном столбце.

Вот пример структуры моего фрейма данных:

dat <- tibble::tribble(
    ~code,    ~geometry,
    "MIE",    list(c(1.24, 45), c(1.25, 45), c(1.25, 46), c(1.24, 45)),
    "MIS",    list(c(1.23, 44), c(1.23, 45), c(1.24, 45), c(1.23, 44))
    )

Я хочу создать объект sf из этого фрейма данных, но R не может распознать столбец геометрии.

Я пробовал форматы списков и функции, такие как st_sf(), st_geometry(), st_polygon(), но безуспешно.

Попытка st_sf(dat) возвращает:

Ошибка в st_sf(dat) :

Error in st_sf(dat) : no simple features geometry column present

Попытка st_polygon(dat$geometry) возвращает:

Error in vapply(x, ncol, 0L) : values must be length 1,
  but FUN(X[[1]]) result is length 0

Есть ли способ преобразовать мой фрейм данных в объект sf?

Я работаю с R версией 3.6.0.

Будет легче помочь, если образец данных будет в формате, который мы можем вставить в скрипт, например, позвонив dput. Также легче помочь, если мы увидим код, который не работает — как именно вы пытались использовать st_sf?

camille 22.05.2019 17:25

Пробовал st_geometry(dat) <- st_sf(st_polygon(dat$geometry)) и dat.sf <- st_sf(dat). Кроме того, я видел, что иногда геометрию можно обернуть дважды в списках типа list(list(c(x1,y1),c(x2,y2))), но это ничего не меняет. Пробовал и с st_sfc, но не уверен, что понял разницу с st_sf...

ldavadan 23.05.2019 09:33
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
3
2
2 470
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я тоже всегда борюсь с этой sf трансформацией, потому что это не так просто.

Первый шаг (и сложная часть) — построить st_object (здесь st_polygon) для каждой отдельной представленной геометрии.

Для этого преобразуйте каждый существующий list в matrix. Как только каждое представление полигона представляет собой n-строку matrix (одна строка для каждой точки), мы преобразуем матрицу в один элемент list для подачи в st_polygon(). Теперь dat$geometry — это список, соответствующим образом классифицированный POLYGONS.

library(tidyverse)

dat %>%
  mutate(geometry = map(geometry,
                        ~ do.call(rbind, .) %>% # make each list a matrix
                          list() %>% # st_polygon() requires a list
                          st_polygon()
                    )
         ) %>% 
  st_as_sf()

Затем последний шаг — вызвать st_as_sf() для всего фрейма данных. Он автоматически обнаружит теперь правильно отформатированный столбец geometry и создаст для вас новый красивый объект sf. Удачного картографирования!

РЕДАКТИРОВАТЬ: Если вы хотите строить многоугольники с отверстиями, процесс аналогичен. st_polygon() будет обрабатывать многоэлементный список так, как если бы первый элемент был многоугольником, а остальные элементы — дырами в первом. Это требует, чтобы вы использовали map дважды, потому что вам все еще нужно построить матрицу из каждого элемента списка, но вам нужно хранить списки сгруппированных матриц вместе для обработки отверстий.

dat2 <- tibble::tribble( ~code, ~geometry, "MIE", list(list(c(1.24, 45), c(1.25, 45), c(1.25, 46), c(1.24, 45)), list(c(1.245,45.5), c(1.246,45.7), c(1.245,45.5))) )

 dat %>%
  mutate(geometry = map(dat$geometry,
                        ~ map(.,
                          ~ do.call(rbind, .) # make each list a matrix
                          ) %>% 
                        st_polygon()
                        )
  ) %>% 
  st_as_sf()

Это работает, спасибо. Есть ли у вас какие-либо идеи для обработки многоугольников с отверстиями? Например: r dat <- tibble::tribble( ~code, ~geometry, "MIE", list(list(c(1.24, 45), c(1.25, 45), c(1.25, 46), c(1.24, 45)), list(c(1.245,45.5), c(1.246,45.7), c(1.245,45.5))) ) Многоугольник — первый список, дырка — второй.

ldavadan 24.05.2019 11:52

Другие вопросы по теме