我有一个 data.table,其中一列包含 JSON。我正在尝试提取内容,以便每个变量都是一列。
library(jsonlite)
library(data.table)
df<-data.table(a=c('{"tag_id":"34","response_id":2}',
'{"tag_id":"4","response_id":1,"other":4}',
'{"tag_id":"34"}'),stringsAsFactors=F)
期望的结果,不引用“其他”变量:
tag_id response_id
1 "34" 2
2 "4" 1
3 "34" NA
我尝试过以下几个版本:
parseLog <- function(x){
if (is.na(x))
e=c(tag_id=NA,response_id=NA)
else{
j=fromJSON(x)
e=c(tag_id=as.integer(j$tag_id),response_id=j$response_id)
}
e
}
这似乎可以很好地检索向量列表(如果 c 被列表替换则为列表),但是当我尝试将列表转换为 data.table 时,某些内容无法按预期工作。
parsed<-lapply(df$a,parseLog)
rparsed<-do.call(rbind.data.frame,parsed)
colnames(rparsed)<-c("tag_id","response_id")
因为第三行缺少值。我怎样才能以R-ish干净的方式解决它?如何使我的解析方法返回缺失值的 NA。或者,是否有像 rbind 那样的参数“fill”可以在 rbind.data.frame 或类似方法中使用?
我使用的数据集有 1100 万行,因此性能很重要。
此外,还有一个与 rbind.data.frame 等效的方法来获取 data.table。那要怎么用呢?当我检查文档时,它向我推荐了 rbindlist 但它提示未使用参数,并且 if call 直接(没有 do.call 它提示解析的类型):
rparsed<-do.call(rbindlist,fill=T,parsed)
编辑:我需要涵盖的情况更一般,在一组 11M 记录中,所有可能的情况都会发生:
df<-data.table(a=c('{"tag_id":"34","response_id":2}',
'{"trash":"34","useless":2}',
'{"tag_id":"4","response_id":1,"other":4}',
NA,
'{"response_id":"34"}',
'{"tag_id":"34"}'),stringsAsFactors=F)
输出应仅包含 tag_id 和 response_id 列。
最佳答案
可能有一种更简单的方法,但这似乎有效:
library(data.table)
library(jsonlite)
df[, json := sapply(a, fromJSON)][, rbindlist(lapply(json, data.frame), fill=TRUE)]
#or if you need all the columns :
#df[, json := sapply(a, fromJSON)][,
# c('tag_id', 'response_id') := rbindlist(lapply(json, data.frame), fill=TRUE)]
输出:
> df[, json := sapply(a, fromJSON)][, rbindlist(lapply(json, data.frame), fill=TRUE)]
tag_id response_id
1: 34 2
2: 4 1
3: 34 NA
编辑:
此解决方案是在编辑问题并提出附加请求后提出的。
有很多方法可以做到这一点,但我发现最简单的一种是创建 data.frame,如下所示:
df[, json := sapply(a, fromJSON)][,
rbindlist(lapply(json, function(x) data.frame(x)[-3]), fill=TRUE)]
# tag_id response_id
#1: 34 2
#2: 4 1
#3: 34 NA
关于json - R将json转换为列表到data.table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34157195/