【问题标题】:How to merge data in to a pre-existing JSON structure in R?如何将数据合并到 R 中预先存在的 JSON 结构中?
【发布时间】:2016-12-06 15:24:57
【问题描述】:

第一次发帖,潜伏已久。要温柔。中度 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。合并它们。用空白填充NAs

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",
    }
  ]
]

【问题讨论】:

    标签: json r jsonlite


    【解决方案1】:

    无法重现您的结果 - 但这是我对您想要实现的目标的猜测。有关代码的帮助,请参见 cmets。

    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]] 提供除了最终索引之外的所有结果都生成一个列表。

    【讨论】:

    • 顺便说一句:我没有进行NA 处理,但我想你可以自己弄清楚。 ;)
    • 我一直在尝试这个,但遇到了一些问题。在运行你的循环时,我收到:Error in 1:nrow(data) : argument of length 0 我可以运行你的代码,就像直接从你的帖子中复制的一样。最后,查看最终输出(也可以从我的角度重现),我发现由于某种原因,被塞入 JSON 结构的数据有时会在 NA 值周围加上引号,而不是剩余值。
    • ad error) 您没有指定data,但我假设这是一个data.frame,其中每一行都必须转换为JSON 对象。如果是这种情况,则不应显示您报告的此错误。 NA 周围的广告引用)我不知道你的实际输入是如何格式化的,但你可能会更接近你想要的 jsonstructure[[mapping[[i]]]]&lt;-ifelse(is.na(data_row[,cn[i]]),"",as.character(data_row[,cn[i]]))
    • 原始data(因子、整数、数字):str(data) data.frame:6 obs. of 13 variables原始jsonstructurestr(jsonstructure) List of 2 $ default:List of 11 $ items :'data.frame': 1 obs. of 2 variables: ..$ id : chr "" ..$ dimensions:'data.frame': 1 obs. of 25 variables:运行mapping=strsplit(data,"\\.")时,会遇到“strsplit(data, "\ \.") : 非字符参数"。我正在添加data&lt;-as.character(data) statement,继续。在colnames(data) = cnshortdata[is.na(shortdata)] &lt;- " " 之后解决NAs
    • 你为什么将strsplit申请到data?在我的回答中,我将它应用于datacolnames(即cn)。所以我猜你应该使用strsplit(colnames(data),"\\.")
    【解决方案2】:

    如果你对 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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多