rjsonlist

Convert data frame to JSON object without outer square brackets


Taking the following data frame:

df <- data.frame(first_name = c("John", "Jane"),
                 last_name  = c("Doe", "Doe2"),
                 age        = c(20, 30))

I want to convert each row into its own list which I then again convert into a JSON body.

I thought about simply using jsonlite::toJSON(df, auto_unbox = TRUE, pretty = TRUE) which leads to:

[
  {
    "first_name": "John",
    "last_name": "Doe",
    "age": 20
  },
  {
    "first_name": "Jane",
    "last_name": "Doe2",
    "age": 30
  }
]

However, the API I'm calling expects a JSON object without the square brackets. I have a vague feeling that the above is not even the problem, because I can only send one "object" (i.e. person) through the API anyway, so I would basically loop through my data frame and convert each row individually.

However, even when I convert just one row of data into a JSON object I get the square brackets whereas I need it without.

What I basically need is:

person1 <- list(first_name = "John",
                last_name   = "Doe",
                age         = 20)

jsonlite::toJSON(person1, auto_unbox = TRUE, pretty = TRUE)

{
  "first_name": "John",
  "last_name": "Doe",
  "age": 20
}

So I either need a smart way to cut the JSON object into pieces which I can then call in individual loops or probably I need to create a list that contains all persons and when I take one list element from that larger list make sure to get it without square brackets.

Any ideas? I also thought if I would first need to e.g. dplyr::group_split my rows and then create the individual JSON rows from there. But this also gives me the outer square brackets:

df |>
  group_split(row_number(), .keep = FALSE) |>
  map(.f = ~jsonlite::toJSON(.x, pretty = TRUE, auto_unbox = TRUE))

[[1]]
[
  {
    "first_name": "John",
    "last_name": "Doe",
    "age": 20
  }
] 

[[2]]
[
  {
    "first_name": "Jane",
    "last_name": "Doe2",
    "age": 30
  }
] 

Solution

  • Here's a working split method. Your insight that a list input leaves off the square brackets you don't want guides us to use as.list() on the input.

    df |> 
      split(1:nrow(df)) |>
      lapply(
        \(x) jsonlite::toJSON(as.list(x), pretty = TRUE, auto_unbox = TRUE)
      )
    # $`1`
    # {
    #   "first_name": "John",
    #   "last_name": "Doe",
    #   "age": 20
    # } 
    # 
    # $`2`
    # {
    #   "first_name": "Jane",
    #   "last_name": "Doe2",
    #   "age": 30
    # }