使用jsonlite解析带有数字标签的json字符串

问题描述

我正在从如下所示的API(我无法控制)中检索json字符串:

{
     "data": [
     {
         "6": {
             "value": "Jamie Stein"
         },"7": {
             "value": 10
         }
     },{
         "6": {
             "value": "Bill Smith"
         },"7": {
             "value": 23
         }
     }
     ],"fields": [
     {
         "id": 6,"label": "Full Name"
     },{
         "id": 7,"label": "Amount"
     }
     ]
 }

我正在使用 jsonlite 包(版本1.7.0)中的fromJSON来解析字符串: res <- from JSON(jsonstr)

生成 data 数据框的名称已损坏。结果看起来像这样:

> res
$data
        value value
1 Jamie Stein    10
2  Bill Smith    23

$fields
  id     label
1  6 Full Name
2  7    Amount

请注意 data 数据框中的“值”列名称。我可以更新 data 数据框的列名,但这似乎使事情变得更加奇怪:

> get_label <- function(x) { res$fields$label[res$fields$id == x]}
> names(res$data) <- sapply(as.integer(names(res$data)),get_label)
> names(res$data)
[1] "Full Name" "Amount"   
> res$data
        value value
1 Jamie Stein    10
2  Bill Smith    23

名称函数表明列名称已更新,但是仅打印数据框表明列名称仍然损坏。

有人可以帮助我了解发生了什么以及对此我可以做什么?在这一点上我很困惑。损坏的数据帧是有问题的-当我使用 write.csv 时,生成文件垃圾

如果有帮助,我正在运行的R版本是4.0.2。

解决方法

嗯,很奇怪。您可以这样做:

library(jsonlite)
library(purrr) # to use 'transpose'
obj <- fromJSON(json,simplifyDataFrame = FALSE)
lapply(obj,function(x){
  as.data.frame(lapply(transpose(x),unlist))
})
# $data
#            X6 X7
# 1 Jamie Stein 10
# 2  Bill Smith 23
# 
# $fields
#   id     label
# 1  6 Full Name
# 2  7    Amount

要获取列名"6""7"

lapply(obj,unlist),check.names = FALSE)
})
# $data
#             6  7
# 1 Jamie Stein 10
# 2  Bill Smith 23
# 
# $fields
#   id     label
# 1  6 Full Name
# 2  7    Amount

编辑:更简单的方法

实际上并不奇怪...

obj <- fromJSON(json)

obj$data是一个数据框,但其列也都是数据框:

> str(obj$data)
'data.frame':   2 obs. of  2 variables:
 $ 6:'data.frame':  2 obs. of  1 variable:
  ..$ value: chr  "Jamie Stein" "Bill Smith"
 $ 7:'data.frame':  2 obs. of  1 variable:
  ..$ value: int  10 23

然后您要:

obj$data <- as.data.frame(lapply(obj$data,"[[","value"))