rnestedjsonlitejsonlines

Convert nested data to json without square brackets


I want to upload ndjson files with nested data.

My code (see below) results in

> {"id":284,"attributes":[{"value":{"T3":1,"T4":0}}]}
> {"id":848,"attributes":[{"value":{"T3":2,"T4":0}}]}

Uploading this data leads to the following error: Bad Request","detail":"json: cannot unmarshal array into Go struct field UserData.attributes of type map[string]interface {}","

Without the square brackets the upload succeeds but short from writing the json "by hand" with paste0, I can´t seem to get the correct format which would be

> {"id":284,"attributes":{"value":{"T3":1,"T4":0}}}
> {"id":848,"attributes":{"value":{"T3":2,"T4":0}}}

auto_unbox did not help either. Any suggestions? Thank you very much

code

con_out <- file("output.json", open = "wb")
set.seed(1234)
data <- data.frame(id = sample(1:1000, 10))
data$value <- data.frame(T3 = sample(1:3, 10, replace = T, prob = c(0.5, 0.25, 0.25)), T4 = 0)
data <- data %>% tidyr::nest(attributes = value)

jsonlite::stream_out(data, con_out)
close(con_out)

edit: The square brackets indicate a list. But if I try to nest data frames, I only manage to nest one level and "loose" attributes.

con_out <- file("output.json", open = "wb")

set.seed(1234)
data <- data.frame(id = sample(1:1000, 10))
data$value <- data.frame(attribues = data.frame(T3 = sample(1:3, 10, replace = T, prob = c(0.5, 0.25, 0.25))))
jsonlite::stream_out(data, con_out, auto_unbox = T)
close(con_out)

> {"id":284,"value":{"T3":1}}
> {"id":848,"value":{"T3":2}}

Solution

  • The column attributes contains data frames with one row each. Each data frame is a list of rows resulting in square brackets. Transform this into a list instead:

    library(jsonlite)
    library(tidyverse)
    
    set.seed(1234)
    data <- data.frame(id = sample(1:1000, 10))
    data$value <- data.frame(T3 = sample(1:3, 10, replace = T, prob = c(0.5, 0.25, 0.25)), T4 = 0)
    data <- data %>% tidyr::nest(attributes = value)
    
    data %>%
      mutate(attributes = attributes %>% map(~ {
        .x %>% as.list() %>% map(as.list)
      })) %>%
      toJSON(pretty = TRUE, auto_unbox = TRUE)
    #> [
    #>   {
    #>     "id": 284,
    #>     "attributes": {
    #>       "value": {
    #>         "T3": 1,
    #>         "T4": 0
    #>       }
    #>     }
    #>   },
    #>   {
    #>     "id": 848,
    #>     "attributes": {
    #>       "value": {
    #>         "T3": 2,
    #>         "T4": 0
    #>       }
    #>     }
    #>   }