如何将数据合并到R中预先存在的JSON结构中?

时间:2016-12-06 15:24:58

标签: json r jsonlite

第一次发布海报,很长一段时间潜伏着。要温柔。中等R用户。我确信有一种更好的,功能性的方式来做我需要的,但感觉我已经研究了没有洞察力的死亡。

我正在尝试将数据集合并到预先存在的JSON结构中。每个JSON结构的一行记录,用于许多序列化JSON请求。

我将数据集加载到13个变量的数据并更改列标题以匹配它们在JSON结构中的显示方式

library(jsonlite)
#### Map Column headers to their respective names in the JSON Structure
colnames(data) <- c("default.A",
                    "default.B",
                    "default.C",
                    "items.A",
                    "items.B.1",
                    "items.B.2",
                    "items.B.3",
                    "items.B.4",
)

创建空白JSON结构。这是需要处理JSON请求的格式。简单的嵌套结构。

sample <- '{
      "default": {
           "A": "",
           "B": "",
           "C": "",
            },
      "items": [{
           "A": "",
           "B": {
                "1": "",
                "2": "",
                "3": "",
                "4": "",
                     }
                }]
           }'

jsonstructure <- fromJSON(sample)

将所有内容都设为DF。合并他们。用空白填充NA

x <- as.data.frame(data)
y <- as.data.frame(jsonstructure)
Z <- merge(x, y, all = TRUE)
Z[is.na(Z)] <- ""

转换为JSON

jsonZ <- toJSON(unname(split(Z, 1:nrow(Z))), pretty=TRUE)
cat(jsonZ)

当前输出不匹配

[
  [
    {
   "default.A": "",
      "default.B": "1234567890",
      "default.C": "",
      "items.A": "1234567890",
      "items.B.1": "1234",
      "items.B.2": "1234",
      "items.B.3": "1234",
      "items.B.4": "1234",
    }
  ],
  [
    {
   "default.A": "",
      "default.B": "0987654321",
      "default.C": "",
      "items.A": "0987654321",
      "items.B.1": "4321",
      "items.B.2": "4321",
      "items.B.3": "4321",
      "items.B.4": "4321",
    }
  ]
]

2 个答案:

答案 0 :(得分:1)

无法重现您的结果 - 但这是我对您想要达到的目标的猜测。请参阅注释以获取有关代码的帮助。

library(jsonlite)

#data.frame with data - you have probably more than 2 rows
data=data.frame(rbind(t(c(NA,1234567890,NA,1234567890,1234,1234,1234,1234)),
                      t(c(1,NA,2,3,1,1000,NA,1234))))

cn=c("default.A",
      "default.B",
      "default.C",
      "items.A",
      "items.B.1",
      "items.B.2",
      "items.B.3",
      "items.B.4")

colnames(data)=cn

#assuming that "." represents structure
mapping=strsplit(cn,"\\.")

#template JSON
jsonstructure <- fromJSON('{"default": {"A": "","B": "","C": ""},
                          "items": [{"A": "",
                                     "B": {"1": "","2": "","3": "","4": ""}}]}')

#now loop through all rows in your data.frame and store them in JSON format
#this will give you a list with JSON objects (i.e., a list of lists)
json_list=lapply(split(data,1:nrow(data)),function(data_row) {
  for (i in seq_along(mapping)) jsonstructure[[mapping[[i]]]]<-data_row[,cn[i]]
  jsonstructure
})

结果:

toJSON(json_list[[2]],pretty = TRUE, auto_unbox=TRUE)
#{
#  "default": {
#    "A": 1,
#    "B": "NA",
#    "C": 2
#  },
#  "items": [
#    {
#      "A": 3,
#      "B": {
#        "1": 1,
#        "2": 1000,
#        "4": 1234
#      }
#    }
#  ]
#} 

只是另一个评论。我的方法使用了[运算符帮助中描述的列表的递归子集:

  

[[可以递归地应用于列表,因此如果单个索引i是长度为p的向量,alist [[i]]等同于alist [[i1]] ... [[ip]]提供除最终索引之外的所有索引都会列在列表中。

答案 1 :(得分:0)

如果你没有设置 jsonlite 包,你可以试试 rjson

library(rjson)

value = c("", "1234690","")
names(value) = c("A","B","C")


value2 = c("","0987654321","","0987654321")
names(value2) = c("1","2","3","4") 

test <- toJSON(list( "default" = value, "items" =  list(c("A" = "", "B" = list(value2))) ))
cat(test)
writeLines(test, "test.json")