将带有空列表的json读入data.frame

时间:2018-01-16 03:14:02

标签: r json

我正在尝试将json文件加载到r中的data.frame中。但是在我的json数据中有一些named list()为空。

这是我的json数据:

json_file1 <- jsonlite::fromJSON('{"txtId":"20180101","data":{"user":[{"id":"123","phone":"00001","realName":"Eric","addr":{},"source":{},"registerDate":{},"type":0,"remain":{}}],"score":[], "live_city":"Nice","live_county":"France"}}')
json_file2 <- jsonlite::fromJSON('{"txtId":"20180102","data":{"user":[{"id":"456","phone":"00002","realName":"Amy","addr":{},"source":{},"registerDate":{},"type":0,"remain":100}],"score":[], "live_city":{},"live_county":{}}}')
json_file = list(json_file1, json_file2)
zt.detail = lapply(json_file, function(y){
  if(!is.null(y$data)) data.frame(y$data, stringsAsFactors = F)
})

当我rbind zt.detail时,我收到错误:

# Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,  : 
#                       arguments imply differing number of rows: 1, 0 

所以我想先将这些list()named list()转移到NA中,然后获取这些数据,然后得到以下结果:

id phone realName type remain addr source registerDate live_city live_county
123 00001  Eric    0    NA     NA     NA    NA            Nice     France  
456 00002  Amy     0    100    NA     NA    NA             NA        NA

2 个答案:

答案 0 :(得分:2)

快速帮助函数以便以后保存输入:

`%|||%` <- function(x, y) {
  ifelse(length(x) == 0 | is.null(x), y, x)
}

验证每个列表和数据框条目并将它们全部放在一个数据框中:

lapply(json_file, function(.x) {

  for (nm in colnames(.x$data$user)) .x$data$user[,nm] <- .x$data$user[,nm] %|||% NA
  for (nm in c("score", "live_city", "live_county")) .x$data$user[,nm] <- .x$data[[nm]] %|||% NA

  .x$data$user

})
## [[1]]
##    id phone realName addr source registerDate type remain score live_city live_county
## 1 123 00001     Eric   NA     NA           NA    0     NA    NA      Nice      France
## 
## [[2]]
##    id phone realName addr source registerDate type remain score live_city live_county
## 1 456 00002      Amy   NA     NA           NA    0    100    NA        NA          NA

答案 1 :(得分:1)

为嵌套的JSON对象创建递归函数。如果有许多JSON文件,则rbind函数部分可以作为for循环。

ff <- function(x) {
  if(is.list(x) && length(x) > 0) lapply(x, ff)
  else if (is.list(x) && length(x) == 0) 'NA'
  else x
  }

output1 <- ff(json_file1$data)
output2 <- ff(json_file2$data)

X <- rbind(data.frame(output1, stringsAsFactors = F), data.frame(output2, stringsAsFactors = F))

修改列名:

colnames(X) <- c('id', 'phone', 'realName', 'addr', 'source', 'registerDate', 'type', 'remain', 'score', 'live_city', 'live_county')

X

   id phone realName addr source registerDate type remain score live_city live_county
1 123 00001     Eric   NA     NA           NA    0     NA    NA      Nice      France
2 456 00002      Amy   NA     NA           NA    0    100    NA        NA          NA