如何用R将带层级的CSV转换为不同深度的嵌套JSON
将扁平化CSV转回嵌套JSON的简便方法
我为方便非IT同事查看i18n翻译系统内容,将嵌套JSON转换为CSV;现在需要把这些CSV转回嵌套JSON。之前尝试用大量条件判断处理层级深度和键的变化,写出了混乱的面条代码但尚未完全生效,想了解更简便的实现方法,比如借助其他R库或技巧。以下是示例数据与期望输出:
示例数据与期望输出
library(tibble) library(jsonlite) df <- tribble( ~ a, ~ b, ~ c, ~ d, ~ value, "a", "c", NA, NA, "q", "a", "d", NA, NA, "r", "a", "e", NA, NA, "s", "a", "f", "i", NA, "t", "a", "f", "j", NA, "u", "b", "g", NA, NA, "v", "b", "h", "k", "m", "x", "b", "h", "k", "n", "y", "b", "h", "k", "o", "z", "b", "h", "k", "p", "aa", "b", "h", "l", NA, "ab" ) # 期望的嵌套JSON对应的列表结构 expected <- list( a = list( c = "q", d = "r", e = "s", f = list( i = "t", j = "u" ) ), b = list( g = "v", h = list( k = list( m = "x", n = "y", o = "z", p = "aa" ), l = "ab" ) ) ) # 输出期望的JSON格式 toJSON(expected, auto_unbox = T, pretty = T)
方法一:使用data.tree库(直观处理层级结构)
data.tree库专门用于处理树状层级数据,能快速将扁平化的CSV转换为嵌套结构:
# 安装并加载库 install.packages("data.tree") library(data.tree) library(jsonlite) # 构建每个条目层级路径(忽略NA值) df$path <- apply(df[, c("a", "b", "c", "d")], 1, function(x) { paste(na.omit(x), collapse = "/") }) # 将数据转换为树结构 tree <- as.Node(df, pathName = "path", valueName = "value") # 递归将树转换为嵌套列表(叶子节点直接取value值) to_nested_list <- function(node) { if (node$isLeaf) { return(node$value) } else { lapply(node$children, to_nested_list) } } # 生成结果并转为JSON result <- to_nested_list(tree) toJSON(result, auto_unbox = TRUE, pretty = TRUE)
方法二:使用purrr递归构建嵌套列表
借助purrr的reduce函数逐行更新嵌套列表,无需额外依赖:
library(purrr) library(jsonlite) # 定义函数:根据单行数据更新嵌套列表 update_nested_list <- function(current_list, row) { # 提取当前行的有效键(排除NA) keys <- na.omit(c(row$a, row$b, row$c, row$d)) target_value <- row$value # 递归定位到目标层级,设置对应值 reduce(keys[-length(keys)], function(l, k) { if (!k %in% names(l)) l[[k]] <- list() l[[k]] }, .init = current_list) %>% `[[<-`(keys[length(keys)], target_value) current_list } # 从空列表开始,逐行迭代构建嵌套结构 result <- reduce(1:nrow(df), function(l, i) update_nested_list(l, df[i, ]), .init = list()) # 转为JSON格式 toJSON(result, auto_unbox = TRUE, pretty = TRUE)
这两种方法都能避免复杂的条件判断,代码更简洁易维护,且能灵活适配不同的层级深度。
内容的提问来源于stack exchange,提问作者Josep Pueyo
相关产品推荐
相关产品推荐

