【问题标题】:Read JSONs in R to data.frame将 R 中的 JSON 读取到 data.frame
【发布时间】:2015-10-13 00:28:22
【问题描述】:

我有 JSON 值列表(实际上它是一个文本文件,其中每一行都是一个 JSON 对象)。像这样:

{ "id": 1, "name": "john", "age": 18, "education": "master" }
{ "id": 2, "name": "jack", "job": "clerk" }
...

某些值可能会丢失(例如,第一项没有“工作”值,第二项没有“教育”和“年龄”)。

我需要在 R 中创建数据框并将所有缺失的列值填充为 NA(如果具有唯一名称的字段至少存在于一行中)。如何更轻松地实现这一目标?

我已经完成的 - 我安装了“rjson”包并将这些行解析为 R 列表。假设 lines 变量是行的字符向量。

library(rjson)
lines <- // initialize "lines" var here
jsons <- sapply(lines, fromJSON)

“jsons”变量变为“列表列表”(每个 JSON 对象都转换为 R 术语中的列表)。怎么转成data.frame?

我想查看我提供的示例的以下数据框:

"id" | "name" | "age" | "education" | "job"
-------------------------------------------
1    | "john" |  18   |  "master"   |   NA
2    | "jack  |  NA   |     NA      | "clerk"

【问题讨论】:

    标签: json r


    【解决方案1】:

    来自plyr,您可以使用rbind.fill 为您添加NAs

    library(plyr)
    rbind.fill(sapply(jsons, data.frame), jsons)
    
    #   id name age education   job
    # 1  1 john  18    master  <NA>
    # 2  2 jack  NA      <NA> clerk
    

    或来自data.table

    library(data.table)
    rbindlist(jsons, fill=T)
    

    dplyr

    library(dplyr)
    bind_rows(sapply(jsons, data.frame))
    

    【讨论】:

    • 不过有一个问题。如果 JSON 中的任何字段具有显式 NULL 值,则此代码不适用于错误消息“参数暗示不同的行数:1, 0”
    • @pkozlov - 我要再次指出 jsonlite 处理这个问题的方法是健壮的检查,并且只会将 null 读取为 data.frame 中的最终 NA 值。
    【解决方案2】:

    未来的我,纠正过去的错误。使用jsonlitestream_in会更有意义

    stream_in(txtfile)
    
    # To test on `txt` from below, try:
    # stream_in(textConnection(txt))
    
    # Found 2 records...
    # Imported 2 records. Simplifying...
    #  id name age education   job
    #1 NA john  18    master  <NA>
    #2  2 jack  NA      <NA> clerk
    

    使用jsonlite 包的fromJSON 函数,在对原始文本数据进行一些内联​​编辑后(我还编辑了id 数据的第一部分以包含明确的null 值,以显示它处理这个):

    fromJSON(paste0("[", gsub("}\n", "},\n", txt), "]"))
    #  id name age education   job
    #1 NA john  18    master  <NA>
    #2  2 jack  NA      <NA> clerk
    

    我所做的只是添加一些格式以将所有 JSON 行包装在 [] 中,并在每个结束 } 的末尾添加一个逗号 - 产生如下所示的输出由jsonlite::fromJSON一次性处理完毕:

    [{"1":"one"},{"2":"two"}]
    

    txt 是您提供的数据行,nullid 变量中:

    txt <- "{ \"id\": null, \"name\": \"john\", \"age\": 18, \"education\": \"master\" }
    { \"id\": 2, \"name\": \"jack\", \"job\": \"clerk\" }"
    

    【讨论】:

    • 我不喜欢这个选项。这个文本文件每行有一个 JSON 对象的原因是该文件可能非常大 - 并且将其作为一个大 JSON 数组读取可能会耗费内存和时间。我认为最好独立处理每一行,甚至可以并行完成。无论如何感谢您的回复。
    • @pkozlov - 如果您使用sapply 循环遍历 R 中的每一行,则无论如何您都必须将您正在操作的任何部分加载到 R 的内存中。没有什么能阻止你从scanning 一次一万行,然后使用这种方法进行处理/并行处理。此外,jsonlite 更适合大数据:stackoverflow.com/a/2062865/496803
    猜你喜欢
    • 1970-01-01
    • 2015-01-13
    • 2011-02-07
    • 2016-07-04
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多