построение json в R с помощью jsonlite - слишком много скобок - PullRequest
1 голос
/ 25 октября 2019

Не эксперт json, но мне нужно то, что, по моему мнению, называется «вложенными объектами», и вместо этого я получаю то, что я считаю «вложенными массивами». Другими словами, некоторые дополнительные скобки. Я пытаюсь преобразовать фрейм данных в данные json, используя jsonlite в R. Воспроизводимый код и результаты ниже. Может кто-нибудь указать мне, как получить данные в правильном формате (строки как вложенные объекты)?

library(jsonlite)

testdat <- data.frame(locationColumn = c("US", "US"),
                      nameColumn = c("General Motors", "Walmart"), 
                      zipColumn = c(19890, 72712) )


jsl <- jsonlite::toJSON(
  list(
    config = list(
      item1 = list("country",
                   "city"),
      item2 = "true",
      item3 = "false",
      item4 = 3
    ),
    rows = split(testdat, 1:nrow(testdat))
  ), 
  auto_unbox = TRUE,
  pretty = TRUE,
  dataframe = "rows",
  simplifyDataFrame = TRUE
)

jsl

Вывод:

{
  "config": {
    "item1": [
      "country",
      "city"
    ],
    "item2": "true",
    "item3": "false",
    "item4": 3
  },
  "rows": {
    "1": [
      {
        "locationColumn": "US",
        "nameColumn": "General Motors",
        "zipColumn": 19890
      }
    ],
    "2": [
      {
        "locationColumn": "US",
        "nameColumn": "Walmart",
        "zipColumn": 72712
      }
    ]
  }
} 

Что мне нужно: (РЕДАКТИРОВАТЬ: Я добавилнемного больше сложности с JSON. Мне нужно держать скобки в «конфигурации», но не иметь скобки в «строках».

{
  "config": {
    "item1": [
      "country",
      "city"
    ],
    "item2": "true",
    "item3": "false",
    "item4": 3
  },
  "rows": {
    "1":
      {
        "locationColumn": "US",
        "nameColumn": "General Motors",
        "zipColumn": 19890
      },
    "2":
      {
        "locationColumn": "US",
        "nameColumn": "Walmart",
        "zipColumn": 72712
      }
  }
} 

1 Ответ

1 голос
/ 25 октября 2019

Вот возможное решение:

library(jsonlite)

testdat <- data.frame(locationColumn = c("US", "US"),
                      nameColumn = c("General Motors", "Walmart"), 
                      zipColumn = c(19890, 72712) )

jsl <- jsonlite::toJSON(
  list(
    rows = split(testdat, 1:nrow(testdat))
  ), 
  auto_unbox = TRUE,
  pretty = TRUE,
  dataframe = "columns",  #change from rows (moves brackets from row level to value level)
  simplifyDataFrame = TRUE
)

#removed the backets if desired
#jsl<-gsub("\\[|\\]", "", jsl)

all.equal(testcase, fromJSON(jsl))
testcase<-fromJSON('{
  "rows": {
    "1":{
         "locationColumn": "US",
         "nameColumn": "General Motors",
         "zipColumn": 19890
        },
    "2":{
         "locationColumn": "US",
         "nameColumn": "Walmart",
         "zipColumn": 72712
        }
  }
}')

all.equal(testcase, fromJSON(jsl))
#[1] TRUE

РЕДАКТИРОВАТЬ Вот утвержденная версия, которая вручную редактирует список списка, чтобы получить правильный формат.

#create a list of the data
top<-list(
  config = list(
    item1 = list("country",
                 "city"),
    item2 = "true",
    item3 = "false",
    item4 = 3
  ),
  rows = split(testdat, 1:nrow(testdat))
)

#edit the data frames store as part of rows
#lapply - lapply loops will parse each column in each row to create a new list
rows<-lapply(top$rows, function(x){
  tempdf<-x
  #collist<-lapply(names(tempdf), function(y){print(tempdf[ , y, drop=T])})
  collist<-lapply(names(tempdf), function(y){tempdf[, y, drop=T]})
  names(collist)<-names(tempdf)
  collist
})

#update the list with the list of list
top$rows<-rows

#make the JSON
jsl <- jsonlite::toJSON(
  top, 
  auto_unbox = TRUE,
  pretty = TRUE,
  dataframe = "columns",
  simplifyDataFrame = TRUE
)
...