在R中展开数据框内嵌套JSON列为新列与行的技术方案
嵌套JSON列分步展开解决方案
出现「data必须是数据框而非列表」错误,核心原因是jsonlite::fromJSON解析后返回的结构不统一——部分字段是单值、部分是数组,导致unnest_wider无法直接处理。以下是完全适配你需求的实现步骤:
1. 先统一JSON解析格式
写一个安全解析函数,把所有JSON字段(包括空数组)都转为数据框结构,避免列表类型干扰:
library(tidyverse) library(jsonlite) # 模拟你的原始数据框 df <- tibble( otherc1 = c("A", "B"), otherc2 = c(1, 2), jsonblob1 = c('{"name":"test1","crits":[{"id":1,"val":10},{"id":2,"val":20}],"tasks":[]}', '{"name":"test2","crits":[{"id":3,"val":30}],"tasks":[{"task":"run","status":"done"}]}'), jsonblob2 = c('{"info":"info1","tags":["tag1","tag2"]}', '{"info":"info2","tags":[]}') ) # 安全解析函数:将所有JSON元素转为数据框,空数组转为空数据框 parse_json_safe <- function(json_str) { parsed <- fromJSON(json_str) map(parsed, function(x) { if (is.list(x) && !is.data.frame(x)) { if (length(x) == 0) tibble() else as_tibble(x) } else { tibble(value = x) } }) %>% bind_cols() } # 解析第一个JSON列,展开单行元素 df_step1 <- df %>% mutate(json_parsed1 = map(jsonblob1, parse_json_safe)) %>% unnest_wider(json_parsed1)
2. 展开多行数组元素(如crits)
用unnest_longer处理需要拆分为多行的数组列,keep_empty = TRUE保证空数组的行不丢失:
df_step2 <- df_step1 %>% unnest_longer(crits, keep_empty = TRUE) %>% unnest_wider(crits, names_sep = "_") # 给数组内字段加前缀,避免列名冲突
3. 单独处理第二个JSON列
因为两个JSON结构不同,重复上述流程处理jsonblob2:
df_step3 <- df_step2 %>% mutate(json_parsed2 = map(jsonblob2, parse_json_safe)) %>% unnest_wider(json_parsed2) %>% unnest_longer(tags, keep_empty = TRUE)
4. 整理最终结果
去掉原始JSON列,按需调整列顺序或处理空值:
final_df <- df_step3 %>% select(otherc1, otherc2, name, starts_with("crits_"), tasks, info, tags) %>% mutate(across(c(tasks, tags), ~replace_na(., ""))) # 可选:把空值替换为空字符串
关键说明
parse_json_safe是核心:确保所有解析后的内容都是数据框,彻底解决「非数据框」的错误- 先展开单行元素,再拆分行数组:避免不同结构的字段互相干扰
keep_empty = TRUE完美适配空数组场景,不会丢失任何原始行- 两个JSON列分别处理,各自结构独立展开,互不影响
内容的提问来源于stack exchange,提问作者Unai Vicente
相关产品推荐
相关产品推荐

