从 R 中的数据框列中提取具有不对称内容的 JSON 数据

Extracting JSON data with asymetric content from a dataframe column in R

我从数据库中加载了一个 table,该数据库包含一列,每一行都有 JSON 数据。 table 类似于下面的示例。 (由于列数据的格式,我无法复制我拥有的 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”)通常包含另一个 header,但只有一个字符数据点。

我的目标是保留现有的数据帧列(例如 id 和名称)并将数据分散在 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]],每个列表都有自己的类型 object,范围从 double 到 data.frame。双 object 包含四个数字观察值(例如 _inv),一些 object 本身就是列表(例如 _person),其中进一步包含“_personid”,然后是一个条目。数据框包含 JSON 数据中每个观测值的日期时间戳。 (每个 _inv 项目都有一个时间戳)

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

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 创建