sf:将几何中的纬度/经度写入单独的列并保留 ID 列

Jor*_*t G 11 r r-sf

我有一个来自 shapefile 的多边形 ID 和它们在几何列中的中心点的 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)
Run Code Online (Sandbox Code Playgroud)

我想将纬度/经度值放入单独的列中,所以我这样做:

library(sf)
centres<- as.data.frame(st_coordinates(df))
Run Code Online (Sandbox Code Playgroud)

这个新的“中心”数据框具有 lat&long 值,但缺少 ID 列。我该如何保留它,或者是否有另一种方法可以将 lat&long 值从几何列中提取到单独的列中,同时将 ID 保持在相同的 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")))
Run Code Online (Sandbox Code Playgroud)

小智 21

使用 unlist + map() 的解决方案

library(tidyverse)

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

separated_coord
Run Code Online (Sandbox Code Playgroud)

  • 这很好用。我认为它应该是一个与“sf”一起提供的函数,类似于“add_coordinates()”。 (7认同)

jay*_*.sf 9

一种可能的方法是将其取消列出。

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
Run Code Online (Sandbox Code Playgroud)

解释

数据结构检查str(df)显示,变量 - geometry- 是list格式化的,这可能不方便。解决这个问题的一种方法是unlist()将其转换为 2 列矩阵,然后将其与第一列重新组合。这样setNames()我们就可以一步分配新的列名称。


lin*_*nog 7

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 
Run Code Online (Sandbox Code Playgroud)

如果您不再关心geometry,请使用df %>% sf::st_set_geometry(NULL)

  • 很好的解决方案。也许翻转 lon 和 lat 标签? (4认同)
  • 自从 XY -&gt; 经度/纬度以来,该问题似乎已得到修复。乔丹发表评论后对其进行了编辑。(“二维点是指 x 和 y、东距和北距、或经度和纬度,我们将它们称为 XY” https://r-spatial.github.io/sf/articles/sf1.html) (2认同)