如何在R中从CSV生成符合指定Schema的JSON
R语言实现CSV转指定结构JSON的方案
先修正目标JSON的结构问题
你给出的目标JSON存在重复键的问题(同一city对象内有多个cityName,同一FreightA对象内有多个Type/FreightSegments),这不符合JSON规范,解析时会导致键值被覆盖。正确的结构应该是每个城市对应city数组中的一个独立对象,调整后的示例如下:
{ "day": "2019-03-14", "city": [ { "cityName": "City1", "FreightA": [ { "Type": 1, "FreightSegments": [{"price": 5, "order": 50}], "Type": 2, "FreightSegments": [{"price": 10, "order": 75}] } ] }, { "cityName": "City2", "FreightA": [ { "Type": 1, "FreightSegments": [{"price": 10, "order": 50}], "Type": 2, "FreightSegments": [{"price": 15, "order": 75}], "Type": 3, "FreightSegments": [{"price": 20, "order": 100}] } ] } ] }
如果要避免重复键的风险,建议将FreightA改为每个Type对应一个独立对象的数组,这个优化方案会在后面说明。
转换步骤(基于你提供的CSV格式)
1. 安装并加载依赖包
使用dplyr处理分组数据,jsonlite生成JSON:
install.packages(c("dplyr", "jsonlite")) library(dplyr) library(jsonlite)
2. 读取并预处理CSV数据
假设你的CSV文件名为data.csv,读取后确保字段类型正确:
df <- read.csv("data.csv", stringsAsFactors = FALSE) # 确保Type为整数类型 df$Type <- as.integer(df$Type)
3. 按城市分组构建结构
将每个城市的Type、price、order转换为目标格式:
city_list <- df %>% group_by(cityName) %>% group_map(function(group, key) { # 构建每个Type对应的键值对(注意重复键的问题) freight_content <- list() for (i in 1:nrow(group)) { freight_content[[paste0("Type", i)]] <- group$Type[i] freight_content[[paste0("FreightSegments", i)]] <- list(list(price = group$price[i], order = group$order[i])) } # 调整为FreightA的结构 freight_a <- list(freight_content) # 返回单个城市的对象 list(cityName = key$cityName, FreightA = freight_a) })
4. 构建顶层JSON结构并输出
提取统一的day值,组合所有城市数据后生成JSON文件:
# 提取日期(假设CSV中所有行的day一致) target_day <- unique(df$day) # 构建最终结构 final_json <- list( day = target_day, city = city_list ) # 输出格式化后的JSON文件 write_json(final_json, "output.json", auto_unbox = TRUE, pretty = TRUE)
优化方案:避免重复键
如果要解决重复键的问题,建议调整FreightA为数组结构,每个元素对应一个Type,示例结构如下:
{ "day": "2019-03-14", "city": [ { "cityName": "City1", "FreightA": [ {"Type": 1, "FreightSegments": [{"price": 5, "order": 50}]}, {"Type": 2, "FreightSegments": [{"price": 10, "order": 75}]} ] } ] }
对应的R代码只需修改分组处理部分:
city_list <- df %>% group_by(cityName) %>% group_map(function(group, key) { # 每个Type生成一个独立对象 freight_a <- pmap(group, function(Type, price, order, ...) { list(Type = Type, FreightSegments = list(list(price = price, order = order))) }) list(cityName = key$cityName, FreightA = freight_a) })
内容的提问来源于stack exchange,提问作者tpscp
相关产品推荐
相关产品推荐

