【问题标题】:Extracting JSON data with asymetric content from a dataframe column in R从 R 中的数据框列中提取具有不对称内容的 JSON 数据
【发布时间】:2022-01-03 21:10:22
【问题描述】:

我从数据库中加载了一个表,该表包含一列,每行都有 JSON 数据。 该表类似于下面的示例。 (由于列数据的格式,我无法复制我拥有的 data.frame)

dataframe_example <- data.frame(id = c(1,2,3),
                                name = c("name1","name2","name3"),
                                JSON_col = c({"_inv": [10,20,30,40]}, "_person": ["_personid": "green"],
                                             {"_inv": [15,22]}, "_person": ["_personid": "blue"],
                                             {"_inv": []}, "_person": ["_personid": "red"]))

我有以下两个问题: 一些项目(例如“_inv”)有时有完整的 4 个数字条目,有时更少,有时什么也没有。其他一些项目(例如“_person”)通常包含另一个标题,但只有一个字符数据点。

我的目标是保留现有的数据框列(例如 id 和 name)并在 json 列中传播数据,这样我就有了包含每个信息点的新列。目标数据框看起来有点像这样:

data.frame(id = c(1,2,3),
           name = c("name1","name2","name3"),
           `_inv_1` = c(10,15,NA),
           `_inv_2` = c(20,22,NA),
           `_inv_3` = c(30,NA,NA),
           `_inv_4` = c(40,NA,NA),
           `_person_id` = c("green","blue","red"))

请记住,我处理 JSON 数据的经验很少,也没有处理不均匀 JSON 数据的经验。

使用purrr 我得到了:

frame <- purrr::map(dataframe_example$JSON_col, jsonlite::fromJSON)

这给了我一个包含 n 个元素的大列表,其中 n 是原始数据帧的长度。 “名称”项包含 n 个列表 [[1]],每个列表都有自己的对象类型,范围从 double 到 data.frame。双精度对象包含四个数值观察,(例如_inv),一些对象本身是列表(例如_person),其中进一步包含“_personid”,然后是单个条目。数据框包含 JSON 数据中每个观察的日期时间戳。 (每个 _inv 项都有一个时间戳)

有没有办法通过从我的“框架”对象中提取数据或完全不同的解决方案来获得上述解决方案?

【问题讨论】:

    标签: r json tidyverse purrr jsonlite


    【解决方案1】:
    library(tidyverse)
    library(jsonlite)
    #> 
    #> Attaching package: 'jsonlite'
    #> The following object is masked from 'package:purrr':
    #> 
    #>     flatten
    
    dataframe_example <-
      data.frame(
        id = c(1, 2, 3),
        name = c("name1", "name2", "name3"),
        JSON_col = c(
          "{\"_inv\": [10,20,30,40], \"_person\": {\"_personid\": \"green\"}}",
          "{\"_inv\": [15,22], \"_person\": {\"_personid\": \"blue\"}}",
          "{\"_inv\": [], \"_person\": {\"_personid\": \"red\"}}"
        )
      )
    
    dataframe_example %>%
      as_tibble() %>%
      mutate(
        JSON_col = JSON_col %>% map(parse_json)
      ) %>%
      unnest_wider(JSON_col) %>%
      unnest(`_inv`) %>%
      unnest(`_inv`) %>%
      unnest(`_person`) %>%
      unnest(`_person`) %>%
      group_by(id, name) %>%
      mutate(inv_id = row_number()) %>%
      pivot_wider(names_from = inv_id, values_from = `_inv`, names_prefix = "_inv_")
    #> # A tibble: 2 x 7
    #> # Groups:   id, name [2]
    #>      id name  `_person` `_inv_1` `_inv_2` `_inv_3` `_inv_4`
    #>   <dbl> <chr> <chr>        <int>    <int>    <int>    <int>
    #> 1     1 name1 green           10       20       30       40
    #> 2     2 name2 blue            15       22       NA       NA
    

    reprex package (v2.0.1) 于 2021 年 11 月 25 日创建

    【讨论】:

    • 非常感谢!提取这些数据很费力,但是使用您的解决方案它可以工作,我正在朝着我想要的方向发展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2021-11-27
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多