如何用R与tidyverse将长表转为嵌套列表并导出为JSON
实现长表到嵌套JSON的转换方案
刚好你提到的tidyverse(尤其是dplyr和tidyr的嵌套功能)加上jsonlite包就能完美解决这个需求,不需要复杂的split操作,分层嵌套+JSON转换一步到位。下面是具体的实现步骤和代码:
核心思路
我们需要把长表按患者→样本→文件的层级进行嵌套,再将嵌套后的结构直接转换为你想要的JSON格式。tidyr::nest可以帮我们轻松实现分层嵌套,jsonlite则负责将R的嵌套数据框转换为标准JSON。
完整代码
# 加载所需包 library(tidyverse) library(jsonlite) library(stringi) # 生成示例长表数据 df = data.frame(patient = c(rep("A",4), rep("B",4)), sample = rep(c("P","R"),4), file = stri_rand_strings(8, 6, '[A-Z]')) # 第一步:按患者+样本分组,嵌套文件列表 nested_files <- df %>% group_by(patient, sample) %>% nest(files = file) %>% # 确保每个文件项是{"file": "XXX"}的格式 mutate(files = map(files, ~ .x %>% transmute(file = file))) # 第二步:按患者分组,嵌套样本列表 final_nested <- nested_files %>% group_by(patient) %>% nest(samples = c(sample, files)) # 转换为格式化的JSON output_json <- toJSON(final_nested, pretty = TRUE, auto_unbox = TRUE) # 查看结果 cat(output_json) # 导出到JSON文件(可选) write_json(final_nested, "patient_samples.json", pretty = TRUE, auto_unbox = TRUE)
代码解释
分层嵌套:
- 先通过
group_by(patient, sample) %>% nest(files = file),把每个患者的每个样本对应的所有文件打包成一个嵌套数据框,存到files列中。 - 用
map配合transmute处理files列,确保每个文件条目都是只包含file键的小数据框,这样转JSON时会生成{"file": "ZZEVYQ"}的结构,而不是冗余的数组格式。 - 再按
patient分组,把每个患者对应的样本和文件列表嵌套成samples列,形成最终的三级嵌套结构。
- 先通过
JSON转换:
jsonlite::toJSON的pretty = TRUE参数让输出的JSON有缩进,可读性更强;auto_unbox = TRUE会把长度为1的向量(比如患者ID)直接输出为字符串,而不是默认的数组格式,完美匹配你想要的JSON结构。
运行这段代码后,你得到的JSON结构会和你手动编写的示例完全一致。
内容的提问来源于stack exchange,提问作者Floris
相关产品推荐
相关产品推荐

