1

Let's say I have this data:

df <- data.frame(value = c("foo", "bar", "baz"))

A simple toJSON gets me this:

[{"value":"foo"},{"value":"bar"},{"value":"baz"}]

But if I need the values as single element arrays, how do I structure the original data? I've tried a few variations involving c(), list(), and I(). Nothing works to get me this output:

[{"value":["foo"]},{"value":["bar"]},{"value":["baz"]}]

2 Answers 2

5

To get the arrangement you want, you need a list of lists

jsonlite::toJSON(list(list("value"="foo"), list("value"="bar"), list("value"="baz")))
# [{"value":["foo"]},{"value":["bar"]},{"value":["baz"]}] 

We can do this with a little help from the tidyverse function mutate_all to convert all the columns to lists.

library(tidyverse)
df %>% mutate_all(as.list) %>% jsonlite::toJSON()
# [{"value":["foo"]},{"value":["bar"]},{"value":["baz"]}] 
Sign up to request clarification or add additional context in comments.

3 Comments

It might be worth mentioning in your answer that to change just the value column, use mutate_at instead of mutate_all: df %>% mutate_at(vars(value), as.list) %>% jsonlite::toJSON().
The list of lists is the more attractive solution but it seemed to have the opposite problem; it converted every value to an array. (The data in the question is just a stripped down test case, I do have a couple of columns.) I was able to get around this with some use of I() and setting auto_unbox to true.
You can control how which values do not get wrapped in an array with unbox. It's always easier to help with a more realistic example.
4

You can pass list to toJSON function.

library(jsonlite)
df <- data.frame(value = c("foo", "bar", "baz"))
# Iterate over rows and put them to list
# Output passed to toJSON output
toJSON(apply(df, 1, as.list))
# [{"value":["foo"]},{"value":["bar"]},{"value":["baz"]}] 

Like this toJSON input is:

apply(df, 1, as.list)

[[1]]
[[1]]$value
[1] "foo"

[[2]]
[[2]]$value
[1] "bar"

[[3]]
[[3]]$value
[1] "baz"

2 Comments

The only caveat is that apply converts the data.frame to a matrix so if you have columns of different datatypes, this might get messy. But for the simple case in the question where there is just one column, this is very nice.
Yeah the question included a pretty stripped down test case, but this looks promising. Seems odd that there's no way for toJSON to treat the data as it's presented.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.