Reputation: 3
Hi! I have an R dataframe in the following format:
user_id email segment name
123 [email protected] new a
234 [email protected] old b
How to trasform it into JSON with desired output:
[
{
"user_id": "123",
"email": "[email protected]",
"custom_data": {
"segment": "new"
},
"tags": [
{ "name": "a" }
]
},
{
"user_id": "234",
"email": "[email protected]",
"custom_data": {
"segment": "old"
},
"tags": [
{ "name": "b" }
]
}
]
I am using the package jsonlite.
Upvotes: 0
Views: 67
Reputation: 160447
Using list-columns with embedded data.frame
s:
dat <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
user_id email segment name
123 [email protected] new a
234 [email protected] old b")
dat$custom_data <- lapply(dat$segment, function(a) data.frame(segment = a))
dat$tags <- lapply(dat$name, function(a) data.frame(name = a))
dat$segment <- dat$name <- NULL
jsonlite::toJSON(dat, pretty = TRUE)
# [
# {
# "user_id": 123,
# "email": "[email protected]",
# "custom_data": [
# {
# "segment": "new"
# }
# ],
# "tags": [
# {
# "name": "a"
# }
# ]
# },
# {
# "user_id": 234,
# "email": "[email protected]",
# "custom_data": [
# {
# "segment": "old"
# }
# ],
# "tags": [
# {
# "name": "b"
# }
# ]
# }
# ]
One difference is that in yours, the "custom_data"
is simply a dictionary/hash, whereas jsonlite
is putting that dictionary within a list (length 1).
If you're a tidyverse-junkie (not meant as bad):
library(dplyr)
dat %>%
mutate(
custom_data = purrr::map(segment, ~ tibble(segment = .x)),
tags = purrr::map(name, ~ tibble(name = .x))
) %>%
select(-segment, -name) %>%
jsonlite::toJSON(., pretty = TRUE)
If you prefer data.table
, then
library(data.table)
as.data.table(dat)[
][, c("custom_data", "tags") :=
.(lapply(dat$segment, function(a) data.frame(segment = a)),
lapply(dat$name, function(a) data.frame(name = a)))
][, c("segment", "name") := NULL
][, jsonlite::toJSON(.SD, pretty = TRUE) ]
or if you still like a "piped" flow of magrittr
,
library(magrittr)
as.data.table(dat) %>%
.[, c("custom_data", "tags") :=
.(lapply(dat$segment, function(a) data.frame(segment = a)),
lapply(dat$name, function(a) data.frame(name = a))) ] %>%
.[, c("segment", "name") := NULL ] %>%
jsonlite::toJSON(., pretty = TRUE)
Upvotes: 1