问题描述
我正在从如下所示的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)
。
> 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"))