如何在R语言中解析包含多个堆叠JSON的文件?
解决R中读取换行分隔JSON(NDJSON/堆叠JSON)并解析为data.frame的问题
你遇到的问题很典型——这个文件是换行分隔JSON(NDJSON)(也叫堆叠JSON),不是标准的JSON数组,所以jsonlite::fromJSON()直接读取会报错,因为标准JSON要求多个对象必须包裹在数组里并用逗号分隔,而你的文件是多个独立的JSON对象连在一起(或每行一个)。下面给你几种可靠的解决方案:
方法1:用jsonlite::stream_in()(推荐,适合大文件)
stream_in()是jsonlite专门为处理NDJSON设计的函数,它会逐行读取并解析JSON对象,自动拼接成data.frame:
library(jsonlite) # 打开文件连接 con <- file("example1.json") # 读取并解析NDJSON foobar <- stream_in(con) # 记得关闭连接 close(con) # 如果只需要特定字段(比如Timestamp和Usefulness) selected_df <- foobar[, c("Timestamp", "Usefulness")] print(selected_df)
运行后就能得到你想要的结果:
Timestamp Usefulness 1 20140101 Yes 2 20140102 No 3 20140103 No
方法2:预处理文件为标准JSON数组(适合小文件)
如果你的文件是多个JSON对象连在一起(没有换行),可以先把它转换成标准的JSON数组再解析:
library(jsonlite) # 读取原始文本 raw_text <- paste(readLines("example1.json", warn = FALSE), collapse = "") # 在每个独立JSON对象之间添加逗号,并包裹成数组 json_array <- paste0("[", gsub("\\}\\s*\\{", "},{", raw_text), "]") # 解析成data.frame foobar <- fromJSON(json_array) # 提取特定字段 selected_df <- foobar[, c("Timestamp", "Usefulness")]
这种方法适合小文件,大文件可能会占用较多内存。
方法3:用data.table高效处理(适合超大文件)
如果你的文件非常大,用data.table的fread结合逐行解析会更高效:
library(data.table) library(jsonlite) # 读取每行JSON字符串 dt <- fread("example1.json", header = FALSE, col.names = "json_str") # 逐行解析并合并成data.table dt_parsed <- rbindlist(lapply(dt$json_str, fromJSON)) # 选择需要的字段 selected_dt <- dt_parsed[, .(Timestamp, Usefulness)] print(selected_dt)
为什么原来的代码报错?
fromJSON()默认只识别标准JSON格式——要么是单个JSON对象,要么是一个包含多个对象的数组(对象之间用逗号分隔)。你的文件是多个独立的JSON对象直接拼接,没有数组包裹和逗号分隔,所以解析器会在第二个对象的开头({"ID":"1A35B"...)抛出语法错误。
内容的提问来源于stack exchange,提问作者ShanZhengYang
相关产品推荐
相关产品推荐

