如何将httr2请求返回的嵌套列表响应转换为DataFrame?
问题描述
使用R语言的httr2工具调用ArcGIS API,接口返回嵌套列表格式的响应,需要将响应中features下的attributes数据转换为每行对应一个OBJECTID、每列对应一个字段的DataFrame,但尝试的方法未成功。相关代码如下:
objectIds <- c(746, 3733, 2271, 2337, 3385, 3610, 2921, 1741, 1883, 885) snes_url <- "https://services1.arcgis.com/gtRkYQyUQLMTM1uS/ArcGIS/rest/services/Species_of_National_Environmental_Significance_Distributions_(public_grids)/FeatureServer/0/query" # here is the query, the actual number of objectIds I might require is arbitrary (though <2000) full_query_params <- list( where = glue::glue("OBJECTID IN ({toString(objectIds[1:5])})"), outFields = "*", outSR = 4326, f = "json" ) # set the request dat_req <-request(snes_url) # Add the query parameters using req_url_query dat_req <- dat_req |> req_url_query(!!!full_query_params) # Perform the request and get the response my_response <- dat_req |> req_perform() |> resp_body_json() bb <- my_response |> pluck('features') bb[[1]]$attributes # these are the data I want in a dataframe, one row per objectID (or in this example, one row per bb list item, bb[[1]], bb[[22]], bb[[3]]), one column per field. # this is one of the methods I have tried for creating a dataframe, but not got to work. extracted_data <- my_response |> pluck('features') |> map_dfr( # iterates over each list and binds rows to a tibble \(x) { tibble( OBJECTID = x |> pluck('OBJECTID'), SCIENTIFIC_NAME = x |> pluck('SCIENTIFIC_NAME '), VERNACULAR_NAME = x |> pluck('VERNACULAR_NAME'), TAXON_GROUP = x |> pluck('TAXON_GROUP') ) } ) extracted_data
解决方法
你的代码存在两个关键问题:
- 目标字段(如
OBJECTID)实际嵌套在attributes子列表中,直接从x中pluck无法获取对应值; SCIENTIFIC_NAME字段名后多了多余空格,导致字段匹配失败。
以下是两种可行的解决方案:
方法一:自动提取所有attributes字段
无需手动指定字段,直接将每个features下的attributes转换为数据框并按行绑定,适合需要所有字段的场景:
library(tidyverse) library(httr2) library(glue) # 保留原请求逻辑 objectIds <- c(746, 3733, 2271, 2337, 3385, 3610, 2921, 1741, 1883, 885) snes_url <- "https://services1.arcgis.com/gtRkYQyUQLMTM1uS/ArcGIS/rest/services/Species_of_National_Environmental_Significance_Distributions_(public_grids)/FeatureServer/0/query" full_query_params <- list( where = glue::glue("OBJECTID IN ({toString(objectIds[1:5])})"), outFields = "*", outSR = 4326, f = "json" ) dat_req <- request(snes_url) |> req_url_query(!!!full_query_params) my_response <- dat_req |> req_perform() |> resp_body_json() # 核心转换代码 extracted_data <- my_response |> pluck("features") |> map_dfr(~ .x$attributes) # 查看结果 extracted_data
方法二:手动指定需要的字段(修正原代码)
如果仅需部分字段,修正字段路径和字段名即可:
extracted_data <- my_response |> pluck('features') |> map_dfr( \(x) { tibble( OBJECTID = x |> pluck('attributes', 'OBJECTID'), SCIENTIFIC_NAME = x |> pluck('attributes', 'SCIENTIFIC_NAME'), VERNACULAR_NAME = x |> pluck('attributes', 'VERNACULAR_NAME'), TAXON_GROUP = x |> pluck('attributes', 'TAXON_GROUP') ) } ) # 查看结果 extracted_data
内容的提问来源于stack exchange,提问作者we need a Mat. Stat.
相关产品推荐
相关产品推荐

