преобразование вложенного списка в dataframe / datatable - PullRequest
0 голосов
/ 03 сентября 2018

Я застрял с довольно конкретной проблемой. У меня есть база данных с полем JSON:

# A tibble: 1 x 3
   field1 field2        JSONfield
    <int> <chr>         <chr>                                                      
1      43 stringgg      "{\"typ\": \"Liste mit Punkten\", \"min~

Теперь, если бы я применил следующий шаблон:

dbGetQuery(pool, mydatabase) %>% 
  mutate(json = map(JSONfield, ~ fromJSON(.) %>% 
                      as.data.frame(stringsAsFactors = FALSE))) %>% 
  unnest(json)

Я бы получил:

# A tibble: 2 x 10
   field1 field2     JSONfield                typ   min   max   items.1 items.2  items.3
    <int> <chr>       <chr>                   <chr> <int> <int> <fct>   <fct>    <fct>  
1     43  stringgg    "{\"typ\": \"Liste mit~ List~ 0     1      first  second   third   
2     43  stringgg    "{\"typ\": \"Liste mit~ List~ 0     1      3       0        7   

Хотя желаемый вывод:

# A tibble: 2 x 10
   field1 field2     JSONfield                typ   min   max   items
    <int> <chr>       <chr>                   <chr> <int> <int> <list>  
1     43  stringgg    "{\"typ\": \"Liste mit~ List~ 0     1      <data.frame~ 

Объект JSON выглядит следующим образом:

{"typ": "Liste mit Punkten",  
   "min": 0, 
   "max": 1, 
   "items": [["first", "second", "third"], 
             [3, 0, 7]]}

Также объекты JSON, с которыми мне приходится иметь дело, имеют подмножество до 7 пар имя / значение, которые могут встречаться или не встречаться в объекте, поэтому я ищу довольно неопределенное решение.

Я очень благодарен за любую помощь по этому вопросу.

1 Ответ

0 голосов
/ 04 сентября 2018

Попробуйте

library(dplyr)
library(purrr)
library(tidyr)
library(jsonlite)

text <- '{"typ": "Liste mit Punkten",  
   "min": 0, 
   "max": 1, 
   "items": [["first", "second", "third"], 
             [3, 0, 7]]}'

dd <- data_frame(field1 = 43, field2 = "stringgg", JSONfield = text)

dd %>% 
  mutate(json = map(JSONfield, ~ fromJSON(.) %>%
      map_if(is.matrix, ~list(as.data.frame(.))) %>% as_tibble
  )) %>%
  unnest() %>%
  select(-JSONfield)
# # A tibble: 1 x 6
#   field1 field2   typ                 min   max items               
#    <dbl> <chr>    <chr>             <int> <int> <list>              
# 1     43 stringgg Liste mit Punkten     0     1 <data.frame [2 × 3]>

Чтобы увидеть, что происходит, мы можем проверить fromJSON(text):

# $typ
# [1] "Liste mit Punkten"

# $min
# [1] 0

# $max
# [1] 1

# $items
#      [,1]    [,2]     [,3]   
# [1,] "first" "second" "third"
# [2,] "3"     "0"      "7"    

Мы конвертируем элемент items, который является матрицей, в кадр данных, а затем помещаем его в список. Наконец, мы преобразуем весь список (содержащий typ, min, max и items) в таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...