如何生成层级JSON:让叶子节点挂载至最近非空父节点
解决层级JSON嵌套的节点挂载问题
核心思路
将数据拆分为Level3非空和为空的两组,分别执行不同嵌套逻辑:非空组按Level1→Level2→Level3层级挂载叶子节点;为空组跳过Level3,直接将叶子节点挂载到最近的非空父节点(Level2),最后合并两组数据再转换为JSON。
具体代码实现
假设你的原始数据框名为df,包含Level1、Level2、Level3、Name、Id列,示例代码如下:
library(dplyr) library(tidyr) library(jsonlite) # 示例测试数据 df <- tibble( Level1 = c("A", "A", "B", "B"), Level2 = c("A1", "A2", "B1", "B2"), Level3 = c("A1a", NA, "B1a", NA), Name = c("Leaf1", "Leaf2", "Leaf3", "Leaf4"), Id = c(1, 2, 3, 4) ) # 处理Level3非NA的情况:完整三级嵌套 df_non_na <- df %>% filter(!is.na(Level3)) %>% nest(children = c(Name, Id)) %>% nest(children = c(Level3, children)) %>% nest(children = c(Level2, children)) # 处理Level3为NA的情况:跳过Level3,直接挂载到Level2 df_na <- df %>% filter(is.na(Level3)) %>% select(-Level3) %>% nest(children = c(Name, Id)) %>% nest(children = c(Level2, children)) # 合并两组数据,按Level1统一整合子节点 final_df <- bind_rows(df_non_na, df_na) %>% group_by(Level1) %>% summarise(children = list(bind_rows(children))) %>% ungroup() # 转换为符合要求的JSON final_json <- toJSON(final_df, pretty = TRUE, auto_unbox = TRUE)
代码说明
- 分组拆分:通过
filter拆分数据,避免空值层级干扰嵌套逻辑; - 差异化嵌套:
- 非空组:依次将叶子节点嵌套到
Level3、Level2、Level1的children下; - 空值组:直接移除
Level3列,将叶子节点嵌套到Level2的children下;
- 非空组:依次将叶子节点嵌套到
- 合并与转JSON:用
bind_rows合并结果,按Level1汇总子节点列表,auto_unbox = TRUE确保不会生成多余的数组包裹。
验证示例结果
生成的JSON结构如下,可见空Level3的叶子节点直接挂载至Level2,无空节点冗余:
[ { "Level1": "A", "children": [ { "Level2": "A1", "children": [ { "Level3": "A1a", "children": [ { "Name": "Leaf1", "Id": 1 } ] } ] }, { "Level2": "A2", "children": [ { "Name": "Leaf2", "Id": 2 } ] } ] }, { "Level1": "B", "children": [ { "Level2": "B1", "children": [ { "Level3": "B1a", "children": [ { "Name": "Leaf3", "Id": 3 } ] } ] }, { "Level2": "B2", "children": [ { "Name": "Leaf4", "Id": 4 } ] } ] } ]
内容的提问来源于stack exchange,提问作者Lyla
相关产品推荐
相关产品推荐

