sf: записать широту / долготу из геометрии в отдельный столбец и сохранить столбец идентификатора

У меня есть df с идентификаторами многоугольника из шейп-файла и их центральными точками в столбце геометрии:

# A tibble: 3 x 2
     ID     geometry
  <dbl> <POINT [°]>
1     1 (117.2 31.8)
2     2 (116.4 40.1)
3     4   (117.9 26)

Я хочу поместить значения широты / долготы в отдельные столбцы, поэтому делаю:

library(sf)
centres<- as.data.frame(st_coordinates(df))

Этот новый «центральный» фрейм данных имеет значения широты и долготы, но пропускает столбец идентификатора. Как я могу его сохранить, или есть другой способ получить значения широты и долготы в отдельные столбцы из столбца геометрии, сохраняя идентификатор в том же df?

dput для фрейма данных:

df <- structure(list(ID = c(1, 2, 4), 
      geometry = structure(list(structure(c(117.2, 31.8), 
      class = c("XY", "POINT", "sfg")), structure(c(116.4, 40.1), 
      class = c("XY", "POINT", "sfg")), structure(c(117.9, 26.0), 
      class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", "sfc"), 
      precision = 0, bbox = structure(c(xmin = 116.4, ymin = 26.0, xmax = 117.9, ymax = 40.1), 
      class = "bbox"), crs = structure(list(epsg = 4326L, 
      proj4string = "+proj=longlat +datum=WGS84 +no_defs"), class = "crs"), n_empty = 0L)), 
      row.names = c(NA, -3L), class = c("sf", "tbl_df", "tbl", "data.frame"), 
      sf_column = "geometry", agr = structure(c(ID = NA_integer_), 
      class = "factor", .Label = c("constant", "aggregate", "identity")))

r sf
person Jorrit G    schedule 17.02.2019    source источник


Ответы (3)


Решение с использованием unlist + map ()

library(tidyverse)

separated_coord <- df %>%
    mutate(lat = unlist(map(df$geometry,1)),
           long = unlist(map(df$geometry,2)))

separated_coord
person Henry Cyranka    schedule 17.02.2019
comment
Спасибо! Работает отлично - person Jorrit G; 17.02.2019
comment
long и lat могут быть неправильными (при использовании epsg 4236). - person william3031; 24.09.2019
comment
Это прекрасно работает. Я думаю, это должна быть функция, которая поставляется с sf, что-то вроде add_coordinates(). - person Rich Pauloo; 16.12.2020

st_geometry можно использовать с dplyr::mutate:

library(magrittr) #for the pipe
df <- df %>%
  dplyr::mutate(lat = sf::st_coordinates(.)[,1],
                lon = sf::st_coordinates(.)[,2])

df
Simple feature collection with 3 features and 3 fields
geometry type:  POINT
dimension:      XY
bbox:           xmin: 116.4 ymin: 26 xmax: 117.9 ymax: 40.1
CRS:            EPSG:4326
# A tibble: 3 x 4
     ID     geometry   lon   lat
* <dbl>  <POINT [°]> <dbl> <dbl>
1     1 (117.2 31.8)  117.  31.8
2     2 (116.4 40.1)  116.  40.1
3     4   (117.9 26)  118.  26 

И если вас больше не волнует geometry, преобразуйте в стандартном фрейме данных с помощью df %>% sf::st_set_geometry(NULL)

person linog    schedule 12.05.2020
comment
Отличное решение. Может быть, переверните ярлыки долготы и широты? - person Jordan; 22.05.2021

Возможный подход - исключить его из списка.

setNames(data.frame(df[[1]], 
                    matrix(unlist(df[2]), ncol=2, byrow=TRUE)), 
         c("ID", "lon", "lat"))

#   ID   lon  lat
# 1  1 117.2 31.8
# 2  2 116.4 40.1
# 3  4 117.9 26.0

Объяснение

Проверка структуры данных с помощью str(df) показывает, что переменная - geometry - имеет формат list, что может быть неудобным. Способ решить эту проблему - unlist() преобразовать ее в матрицу с двумя столбцами и собрать заново с первым столбцом. С setNames() мы можем назначать новые имена столбцов за один шаг.

person jay.sf    schedule 17.02.2019
comment
Спасибо! Работает отлично - person Jorrit G; 17.02.2019