如何在DataFrame中展开命名列表?优化嵌套数组JSON读取方案
处理嵌套JSON的读取与列展开问题
原始JSON格式
{ "year": 2019, "numberofhomes": 480, "meetingdate": "2019-02-09", "votes": [ { "date": "2019-01-23", "votes": 39 }, { "date": "2019-02-01", "votes": 124 }, { "date": "2019-02-09", "votes": 164 } ] }
当前读取情况
使用jsonlite::read_json时,不同参数会得到不同结果:
情况1:simplifyDataFrame = FALSE
读取后转为tibble,votes列呈现为命名列表:
jsonlite::read_json("sources/votes-2019.json", simplifyDataFrame = FALSE) %>% as_tibble() # A tibble: 3 x 4 year numberofhomes meetingdate votes <int> <int> <chr> <list> 1 2019 480 2019-02-09 <named list [2]> 2 2019 480 2019-02-09 <named list [2]> 3 2019 480 2019-02-09 <named list [2]>
情况2:simplifyDataFrame = TRUE
生成带$前缀的嵌套列:
jsonlite::read_json("sources/votes-2019.json", simplifyDataFrame = TRUE) %>% as_tibble() # A tibble: 3 x 4 year numberofhomes meetingdate votes$date $votes <int> <int> <chr> <chr> <int> 1 2019 480 2019-02-09 2019-01-23 39 2 2019 480 2019-02-09 2019-02-01 124 3 2019 480 2019-02-09 2019-02-09 164
解决方法
方法1:展开嵌套列(适配simplifyDataFrame = TRUE结果)
用tidyr::unnest_wider将嵌套的votes列拆分为常规独立列:
library(jsonlite) library(tidyr) library(dplyr) read_json("sources/votes-2019.json", simplifyDataFrame = TRUE) %>% as_tibble() %>% unnest_wider(votes, names_sep = "_")
执行后会得到扁平结构的DataFrame,包含year、numberofhomes、meetingdate、votes_date、votes_votes列。
方法2:处理列表列(适配simplifyDataFrame = FALSE结果)
用purrr::map_dfr将列表列转为tibble,再与原数据合并:
library(jsonlite) library(purrr) library(dplyr) data <- read_json("sources/votes-2019.json", simplifyDataFrame = FALSE) %>% as_tibble() bind_cols( data %>% select(-votes), map_dfr(data$votes, as_tibble) )
最终生成的DataFrame会直接包含date和votes常规列,与JSON内字段对应。
更优读取方式:直接使用jsonlite::fromJSON
fromJSON默认自动简化嵌套结构,配合unnest_wider步骤更简洁:
library(jsonlite) library(tidyr) library(dplyr) fromJSON("sources/votes-2019.json") %>% as_tibble() %>% unnest_wider(votes)
这种方式无需额外处理列表或嵌套列的命名问题,直接输出扁平结构的DataFrame。
内容的提问来源于stack exchange,提问作者Rob Hanssen
相关产品推荐
相关产品推荐

