将嵌套列表转换为数据框/数据表

时间:2018-09-03 19:40:55

标签: r json dataframe datatable dplyr

我遇到了一个非常特殊的问题。我有一个带有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 :(得分:1)

尝试

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元素转换为数据框,然后将其放入列表中。最后,我们将整个列表(包含typminmaxitems)转换为小标题。