最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - Convert data frame to JSON object without outer square brackets - Stack Overflow

programmeradmin3浏览0评论

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

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
  }
] 
Share Improve this question asked Mar 25 at 15:57 deschendeschen 11.1k4 gold badges29 silver badges66 bronze badges 3
  • Adding a simple gsub with lapply does not work? Is auto_unbox = TRUE doing somethin useful here? – Friede Commented Mar 25 at 16:05
  • Well you can remove the brackets by doing df |> group_split(row_number(), .keep = FALSE) |> map(~ gsub("^\\[|\\]$", "",toJSON(.x, auto_unbox = TRUE))) giving {"first_name":"John","last_name":"Doe","age":20} - hope it helps – Tim G Commented Mar 25 at 16:08
  • 4 I think you already answered it yourself -- to get that output directly from jsonlite, you need to convert single-row frame to a list first. For example - stackoverflow/a/79095334/646761 – margusl Commented Mar 25 at 16:36
Add a comment  | 

3 Answers 3

Reset to default 2

Use toJSON(unbox(...)) with by giving the character vector shown.

library(jsonlite)

c(by(df, 1:nrow(df), \(x) toJSON(unbox(x))))

##                                                             1 
##  "{\"first_name\":\"John\",\"last_name\":\"Doe\",\"age\":20}" 
##                                                             2 
## "{\"first_name\":\"Jane\",\"last_name\":\"Doe2\",\"age\":30}" 


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
# } 

You can try

split(df, seq(nrow(df))) |>
  lapply(\(.) gsub('^\\[|\\]$', '', jsonlite::toJSON(., pretty=TRUE)))
$`1`

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

$`2`

  {
    "first_name": "Jane",
    "last_name": "Doe2",
    "age": 30
  }

if you really need each row as separate list element structured in JSON format.

发布评论

评论列表(0)

  1. 暂无评论