0

Hi! I have an R dataframe in the following format:

   user_id   email      segment name
     123    a@gmail.com   new     a
     234    b@gmail.com   old     b

How to trasform it into JSON with desired output:

[
      {
        "user_id": "123",
        "email": "a@gmail.com",
        "custom_data": {
          "segment": "new"
        },
        "tags": [
          { "name": "a" }
        ]
      },
      {
        "user_id": "234",
        "email": "b@gmail.com",
        "custom_data": {
          "segment": "old"
        },
        "tags": [
          { "name": "b" }
        ]
      }
    ]

I am using the package jsonlite.

1

Using list-columns with embedded data.frames:

dat <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
   user_id   email      segment name
     123    a@gmail.com   new     a
     234    b@gmail.com   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": "a@gmail.com",
#     "custom_data": [
#       {
#         "segment": "new"
#       }
#     ],
#     "tags": [
#       {
#         "name": "a"
#       }
#     ]
#   },
#   {
#     "user_id": 234,
#     "email": "b@gmail.com",
#     "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)
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy正规365体育投注

Not the answer you're looking for? Browse other questions tagged or ask your own question.