使用 jsonlite 解析带有数字标签的 json 字符串
Using jsonlite to parse json string with number labels
我正在从 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
names函数表明列名已更新,但仅打印数据帧表明列名仍然损坏。
有人可以帮助我了解正在发生的事情以及我可以做些什么吗?在这一点上我很困惑。损坏的数据帧有问题 - 当我使用 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, function(x){
as.data.frame(lapply(transpose(x), 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"))
我正在从 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
names函数表明列名已更新,但仅打印数据帧表明列名仍然损坏。
有人可以帮助我了解正在发生的事情以及我可以做些什么吗?在这一点上我很困惑。损坏的数据帧有问题 - 当我使用 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, function(x){
as.data.frame(lapply(transpose(x), 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"))