Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R将json转换为list到data.table_Json_R_List_Dataframe_Data.table - Fatal编程技术网

R将json转换为list到data.table

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

我有一个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)
我尝试了以下几种版本:

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