Преобразовать R-кадр данных в JSON - PullRequest
0 голосов
/ 27 марта 2020

Hi! У меня есть 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.

1 Ответ

1 голос
/ 27 марта 2020

Использование списков-столбцов со встроенными data.frame s:

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" - это просто словарь / га sh, тогда как jsonlite ставит этот словарь в списке (длина 1).

Если вы склонны к тишине ie (не так уж плохо):

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,

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