避免嵌套循环:将层级data_frame转换为指定格式嵌套JSON
不用嵌套循环将层级数据框转换为嵌套JSON
这问题我熟,用tidyverse生态里的工具就能轻松搞定,完全不用手动写嵌套循环。核心思路是用分组嵌套+映射转换的方式,按层级逐步构建嵌套结构,最后转成JSON。
所需工具包
我们需要用到三个包:
dplyr:用于数据分组和嵌套操作purrr:用于向量式的映射转换,替代循环jsonlite:用于将R对象转换为JSON格式
完整代码实现
先把你的数据框构造出来(我加了set.seed让随机结果可复现),然后一步步处理:
library(dplyr) library(purrr) library(jsonlite) # 构造你的数据框 set.seed(123) df <- tibble( parent = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C"), child1 = c("a", "a", "b", "b", "c", "d", "d", "e", "e", "f", "f", "f", "f", "g", "g"), child2 = c("aa", "ab", "ba", "bb", "ca", "da", "db", "ea", "eb", "fa", "fb", "fc", "fd", "ga", "gb"), value = sample(seq(1,100,1), 15) ) # 分层构建嵌套结构,全程无嵌套循环 nested_data <- df %>% # 第一步:按parent+child1分组,把child2和value打包成子数据集 group_by(parent, child1) %>% nest(child2_data = c(child2, value)) %>% # 第二步:把每个child2的数据集转换成{child2: value}的命名列表 mutate(child1_data = map(child2_data, ~set_names(.x$value, .x$child2))) %>% select(-child2_data) %>% # 第三步:按parent分组,把child1和对应的子数据打包 group_by(parent) %>% nest(children = c(child1, child1_data)) %>% # 第四步:把每个parent的子数据转换成{child1: 子列表}的命名列表 mutate(parent_data = map(children, ~set_names(.x$child1_data, .x$child1))) %>% select(-children) # 转换为格式化的嵌套JSON nested_json <- nested_data %>% deframe() %>% # 将数据框转为以parent为键的命名列表 toJSON(pretty = TRUE) # 打印结果 cat(nested_json)
代码解释
- 分组嵌套:用
group_by()+nest()把底层数据按上层维度打包,避免了手动循环遍历每个分组 - 映射转换:用
purrr::map()对每个分组的数据进行批量转换,生成{key: value}的结构,这是向量式操作,比循环高效得多 - 最终转换:
deframe()把数据框转换成命名列表,再用toJSON()输出格式化的JSON,结构完全符合你的层级需求
输出结果
运行后会得到如下格式的嵌套JSON(因随机种子固定,数值和示例一致):
{ "A": { "a": { "aa": 31, "ab": 79 }, "b": { "ba": 51, "bb": 14 }, "c": { "ca": 67 } }, "B": { "d": { "da": 42, "db": 50 }, "e": { "ea": 4, "eb": 70 } }, "C": { "f": { "fa": 25, "fb": 24, "fc": 100, "fd": 22 }, "g": { "ga": 45, "gb": 76 } } }
内容的提问来源于stack exchange,提问作者ottlngr
相关产品推荐
相关产品推荐

