手动解析GeoJSON为DataFrame/tibble的tidyverse分步实现
分步将GeoJSON转换为Tibble(基于tidyverse)
问题说明
给定test.geojson文件内容如下:
{"type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "VAR_1": 31,"VAR_2": "abc","VAR_3": 255 }, "geometry" : null }, { "type": "Feature", "properties": { "VAR_1": 23,"VAR_2": "def","VAR_3": 876 }, "geometry" : null } ]}
期望转换后的tibble结构(假设geometry为坐标数组):
# A tibble: 2 x 4 VAR_1 VAR_2 VAR_3 geometry <dbl> <chr> <dbl> <list> 1 31 abc 255 <dbl [2]> 2 23 def 876 <dbl [2]>
尝试的代码无法正确添加geometry字段:
# Read geojson js <- jsonlite::read_json("test.geojson") # Iterate through each features ... map_dfr(1:length(js$features), .f = function(i){ df <- js$features[[i]]$properties # this works but only importing VAR_1, VAR_2, VAR_3 df |> mutate(geometry = js$features[[i]]$geometry) # this does not work })
分步解决方案
1. 加载依赖包
library(tidyverse) library(jsonlite)
2. 读取GeoJSON文件
# 读取文件,得到嵌套列表结构的GeoJSON数据 js <- read_json("test.geojson")
3. 遍历并转换每个Feature
核心问题在于:feature$properties是命名列表,而非tibble,直接调用mutate会失效。需要先将其转换为单行tibble,再添加geometry列:
result_tbl <- map_dfr(js$features, function(feature) { # 将properties转换为单行tibble properties_tbl <- as_tibble(feature$properties) # 用list()包裹geometry值,保留其嵌套结构(坐标数组/GeoJSON对象) properties_tbl |> mutate(geometry = list(feature$geometry)) })
4. 验证结果
如果将示例中的geometry: null替换为实际坐标(比如[116.397, 39.908]),运行后会得到符合预期的tibble:
print(result_tbl) # # A tibble: 2 × 4 # VAR_1 VAR_2 VAR_3 geometry # <dbl> <chr> <dbl> <list> # 1 31 abc 255 <dbl [2]> # 2 23 def 876 <dbl [2]>
关键要点
- 必须先将
feature$properties转换为tibble,才能使用dplyr的mutate等函数 - 用
list(feature$geometry)包裹几何数据,确保它在tibble中以列表列形式存在,保留原始的GeoJSON几何结构(支持Point、Polygon等所有类型)
内容的提问来源于stack exchange,提问作者Michaël
相关产品推荐
相关产品推荐

