将 R 数据帧转换为 JSON

Transform R dataframe into JSON

您好!我有以下格式的 R 数据框:

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

如何将其转换为具有所需输出的 ​​JSON:

[
      {
        "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" }
        ]
      }
    ]

我正在使用 jsonlite 包。

使用嵌入 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"
#       }
#     ]
#   }
# ] 

一个区别是,在您的 "custom_data" 中,dictionary/hash 只是一个 dictionary/hash,而 jsonlite 是将该字典放入列表(长度为 1)中。

如果你是一个 tidyverse-junkie(不是那么坏):

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)

如果您更喜欢data.table,那么

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

或者如果您仍然喜欢 magrittr 的 "piped" 流程,

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)