Peter Golovatyi
Peter Golovatyi

Reputation: 3

Transform R dataframe into JSON

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

Answers (1)

r2evans
r2evans

Reputation: 160447

Using list-columns with embedded data.frames:

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

Related Questions