将 sf 对象列表转换为一个 sf

Posted

技术标签:

【中文标题】将 sf 对象列表转换为一个 sf【英文标题】:Convert a list of sf objects into one sf 【发布时间】:2018-12-21 02:46:16 【问题描述】:

我有一个 sf 对象列表,我想对其进行行绑定以创建单个 sf 对象。我正在寻找一个类似于data.table::rbindlist 的函数,它可以有效地堆叠各个对象。

可重现示例的数据:

my_list <- structure(list(structure(list(idhex = 4L, geometry = structure(list(
            structure(c(664106.970004623, 6524137.38910266), class = c("XY", 
            "POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = 664106.970004623, 
            ymin = 6524137.38910266, xmax = 664106.970004623, ymax = 6524137.38910266
            ), class = "bbox"), crs = structure(list(epsg = 32633L, proj4string = "+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"), class = "crs"), n_empty = 0L)), row.names = 1L, class = c("sf", 
            "data.frame"), sf_column = "geometry", agr = structure(c(idhex = NA_integer_), .Label = c("constant", 
            "aggregate", "identity"), class = "factor")), structure(list(
            idhex = 9, geometry = structure(list(structure(c(665491.220375992, 
            6525002.7560692), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", 
            "sfc"), precision = 0, bbox = structure(c(xmin = 665491.220375992, 
            ymin = 6525002.7560692, xmax = 665491.220375992, ymax = 6525002.7560692
            ), class = "bbox"), crs = structure(list(epsg = 32633L, proj4string = "+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs"), class = "crs"), n_empty = 0L)), row.names = 1L, class = c("sf", 
            "data.frame"), sf_column = "geometry", agr = structure(c(idhex = NA_integer_), .Label = c("constant", 
            "aggregate", "identity"), class = "factor"))), .Dim = 1:2, .Dimnames = list(
            ".", NULL))

请注意,data.tablesf 库还不完全兼容。所以rbindlist函数返回了一个不被识别为`sf对象的对象。

single_sf <- rbindlist(my_list)
class(single_sf)

【问题讨论】:

虽然您可以轻松转换为 sf(如果 crs 相同)sf::st_as_sf(data.table::rbindlist(my_list)) 为了完整起见,@timelyportfolio 还写了mapedit:::combine_list_of_sf 来实现这一点。也可能值得监视github.com/r-spatial/mapedit/issues/46,因为专用的bind_rows_sf 可能会在某个阶段在 sf 中实现。 【参考方案1】:
df <- do.call(rbind, my_list)

> class(df)
[1] "sf"         "data.frame"

值得注意的是dplyr::bind_rowspurrr::map_dfr不适用于sf对象,因此rbind在这种情况下更好。

【讨论】:

另外值得注意的是列表元素的crs需要匹配...【参考方案2】:

这是一个老问题,但值得注意的是,dplyr (> 0.9) 的最新版本可以绑定 sf 对象的行(在列表中或不在列表中):

single_sf <- dplyr::bind_rows(my_list)
class(single_sf)
[1] "sf"         "data.frame"

其他包也提供了可用于绑定sf 对象的选项(例如 mapedit:::combine_list_of_sf()sf:::rbind.sfdata.table::rbindlist),除了上面提到的 do.call() 选项(有关讨论和一些基准测试,请参阅 https://github.com/r-spatial/sf/issues/798#)。但是dplyr 选项也适用于具有包含不同列数的数据框的sf 对象,这是do.call()sf:::rbind.sf()data.table::rbindlist() 无法做到的,这对我处理@ 列表很重要987654335@ 不同列数的对象。

【讨论】:

以上是关于将 sf 对象列表转换为一个 sf的主要内容,如果未能解决你的问题,请参考以下文章

java将JSON字符串转换为实体类对象,基于net sf json实现

java net.sf.json 如何将javabean的首字母转换为大写

JSON 字符串 与 java 对象的转换

通过R中的sf将经度和纬度序列转换为多边形

net.sf.json方法使用详解

JSON 与JAVA数据的相互转换