如何利用给定JSON文件创建指定格式的R DataFrame
问题:重构JSON加载后的DataFrame结构
原始JSON内容如下:
{"data":[{"Alpha":"A","A":"4.63"}, {"Beta":"B","B":"4.15"}, {"Omega":"O","O":"13.6"}, {"Theta":"T","T":"1.28"}, {"Sigma":"S","S":"1.1"}]}
使用jsonlite包加载后得到的DataFrame为:
library(jsonlite) data <- fromJSON("provdata.json")$data data # Alpha A Beta B Omega O Theta T Sigma S # 1 A 4.63 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> # 2 <NA> <NA> B 4.15 <NA> <NA> <NA> <NA> <NA> <NA> # 3 <NA> <NA> <NA> <NA> O 13.6 <NA> <NA> <NA> <NA> # 4 <NA> <NA> <NA> <NA> <NA> <NA> T 1.28 <NA> <NA> # 5 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> S 1.1
期望得到的结构化DataFrame格式:
restructured_data # Name Value # 1 Alpha 4.63 # 2 Beta 4.15 # 3 Omega 13.60 # 4 Theta 1.28 # 5 Sigma 1.10
解决方案
方法1:基础循环处理
适合不依赖额外工具包的场景,通过遍历每行提取非NA的键值对:
library(jsonlite) data <- fromJSON("provdata.json")$data # 初始化结果数据框 restructured_data <- data.frame(Name = character(), Value = numeric(), stringsAsFactors = FALSE) for (i in seq_len(nrow(data))) { # 获取当前行非NA的列名 non_na_cols <- colnames(data)[!is.na(data[i, ])] # 提取名称和数值 name <- non_na_cols[1] value <- as.numeric(data[i, non_na_cols[2]]) # 追加到结果 restructured_data <- rbind(restructured_data, list(Name = name, Value = value)) } # 格式化数值为两位小数(可选) restructured_data$Value <- round(restructured_data$Value, 2) print(restructured_data)
方法2:使用tidyverse工具链(简洁高效)
借助tidyr和dplyr的函数,通过长格式转换实现:
library(jsonlite) library(tidyverse) data <- fromJSON("provdata.json")$data restructured_data <- data %>% # 添加行号用于分组 mutate(row_id = row_number()) %>% # 转换为长格式 pivot_longer(-row_id, names_to = "col", values_to = "val") %>% # 过滤空值 filter(!is.na(val)) %>% # 按行分组提取名称和数值 group_by(row_id) %>% summarise( Name = col[1], Value = as.numeric(val[2]) ) %>% # 清理并格式化 ungroup() %>% select(-row_id) %>% mutate(Value = round(Value, 2)) print(restructured_data)
方法3:直接处理原始JSON列表(最优效率)
跳过宽格式DataFrame转换,直接处理fromJSON返回的原始列表,减少数据操作步骤:
library(jsonlite) library(purrr) # 读取原始JSON列表 raw_data <- fromJSON("provdata.json")$data # 遍历每个列表元素,提取目标信息 restructured_data <- map_dfr(raw_data, function(item) { # 通过键名长度区分名称(如Alpha)和数值列(如A) name_col <- names(item)[nchar(names(item)) > 1] value_col <- names(item)[nchar(names(item)) == 1] data.frame( Name = name_col, Value = as.numeric(item[[value_col]]), stringsAsFactors = FALSE ) }) # 格式化数值为两位小数 restructured_data$Value <- round(restructured_data$Value, 2) print(restructured_data)
内容的提问来源于stack exchange,提问作者KD17
相关产品推荐
相关产品推荐

