R将json转换为list到data.table
我有一个data.table,其中一列包含JSON。我试图提取内容,以便每个变量都是一列R将json转换为list到data.table,json,r,list,dataframe,data.table,Json,R,List,Dataframe,Data.table,我有一个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"}'),stringsA
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)
我尝试了以下几种版本:
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
}
parseLog可能有一种更简单的方法,但这似乎有效:
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中的其他变量不感兴趣。。。他们中的许多人。回答得很好!尽管如此,该解决方案并不认为要忽略的变量的数量是高的,这意味着可以构建的数据帧可以是巨大的。有没有办法避免这种情况?可能会逐个添加相关的列?json列中的变量顺序是否有保证?即使将整个“json”列用作中间步骤,也需要大量内存。我知道我很挑剔,只是试图涵盖所有可能的问题。当我在stackoverflow上发布答案时,我不知道每个OP的R技能或水平。因此,为了适应大多数OP,我尝试尽可能明确。我只是提供了解决问题中特定任务的答案。为了说明问题,上面的答案分两步写。我发现很容易将中间步骤与下一步结合起来,以减少内存。基本上,只需在第二步中将json
替换为sapply(a,fromJSON)
。此外,我在上面使用了data.frame(x)[-3])
,但如果有1000列,则只需将-3
替换为要保留的列名的字符向量即可。我想这很容易做到。首先,谢谢你的帮助。我为误解承担责任,因为我对这个问题所做的两次更新引起了混乱。其次,选择所需的列而不是消除不必要的列的想法是行不通的,因为在某些情况下,列2将不存在。“a”栏上的NA也不能让事情变得简单。如果我尝试用{}替换NA,后续步骤将忽略这些行。是的,你提到的简化很简单,只是想说明,如果可能的话,提高内存效率是很重要的。
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)
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
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