json - R 到使用 JSONLITE 的分层 JSON?

标签 json r jsonlite

我的最终目标是使用 D3js 从分层 JSON 文件创建树可视化。

我需要表示的层次结构是这个图,其中 A 有子 B、C、D; B 有 child E、F、G; C有 child H,I; D没有 child 。节点将有多个键:值对。为简单起见,我只列出了 3 个。

                             -- name:E
                            |   type:dkBlue
                            |   id: 005
                            |
                            |-- name:F
            -- name:B ------|   type:medBlue 
            |  type:blue    |   id: 006
            |  id:002       |
            |               |-- name:G
            |                   type:ltBlue
 name:A ----|                   id:007     
 type:colors|
 id:001     |-- name:C  ----|-- name:H
            |   type:red    |   type:dkRed         
            |   id:003      |    id:008
            |               |  
            |               |
            |               |-- name:I
            |                   type:medRed
            |                   id:009
            |-- name:D
                type:green
                id: 004

我在 R 中的源数据如下所示:

nodes <-read.table(header = TRUE, text = "
ID name type
001 A   colors
002 B   blue
003 C   red
004 D   green
005 E   dkBlue
006 F   medBlue
007 G   ltBlue
008 H   dkRed
009 I   medRed
")

links <- read.table(header = TRUE, text = "
startID  relation endID    
001      hasSubCat 002
001      hasSubCat 003
001      hasSubCat 004
002      hasSubCat 005
002      hasSubCat 006
002      hasSubCat 007
003      hasSubCat 008
003      hasSubCat 009
")

我必须将其转换为以下 JSON:

{"name": "A",
 "type": "colors",
 "id" : "001",
 "children": [
    {"name": "B",
      "type": "blue",
      "id"  : "002", 
      "children": [
          {"name": "E",
           "type": "dkBlue",
           "id"  : "003"},
          {"name": "F", 
           "type": "medBlue",
           "id": "004"},
          {"name": "G", 
           "type": "ltBlue",
           "id": "005"}
    ]},
    {"name": "C",
      "type": "red",
      "id"  : "006", 
      "children": [
          {"name": "H",
           "type": "dkRed",
           "id"  : "007"},
          {"name": "I", 
           "type": "dkBlue",
           "id": "008"}
    ]},
    {"name": "D",
      "type": "green",
      "id"  : "009"}
]}  

如果您能提供任何帮助,我将不胜感激!

[更新 2017-04-18]

根据 Ian 的引用资料,我查看了 R 的 data.tree。如果我如下所示重组我的数据,我可以重新创建我的层次结构。请注意,我已经丢失了每个节点之间的关系类型 (hasSubcat),其值在现实生活中可能因每个链接/边缘而异。如果我能得到一个可行的层次结构,我愿意(暂时)放手。 data.tree 修改后的数据:

df <-read.table(header = TRUE, text = "
paths  type     id 
A      colors   001
A/B    blue     002
A/B/E  dkBlue   005
A/B/F  medBlue  006
A/B/G  ltBlue   007
A/C    red      003
A/C/H  dkRed    008
A/C/I  medRed   009
A/D    green    004
")

myPaths <- as.Node(df, pathName = "paths")
myPaths$leafCount / (myPaths$totalCount - myPaths$leafCount)
print(myPaths, "type", "id", limit = 25)

打印显示我在原始帖子中勾勒出的层次结构,甚至包含每个节点的键:值。不错!

  levelName    type id
1 A          colors  1
2  ¦--B        blue  2
3  ¦   ¦--E  dkBlue  5
4  ¦   ¦--F medBlue  6
5  ¦   °--G  ltBlue  7
6  ¦--C         red  3
7  ¦   ¦--H   dkRed  8
8  ¦   °--I  medRed  9
9  °--D       green  4

再一次,我不知道如何将它从树转换为嵌套的 JSON。这里的例子https://ipub.com/data-tree-to-networkd3/与大多数示例一样,假设键值对仅存在于叶节点上,而不存在于分支节点上。我认为答案是创建一个嵌套列表以输入 JSONIO 或 JSONLITE,但我不知道该怎么做。

最佳答案

data.tree 非常有用,可能是实现目标的更好方法。为了好玩,我将提交一个更迂回的方式来使用 igraphd3r 实现嵌套的 JSON

nodes <-read.table(header = TRUE, text = "
ID name type
001 A   colors
002 B   blue
003 C   red
004 D   green
005 E   dkBlue
006 F   medBlue
007 G   ltBlue
008 H   dkRed
009 I   medRed
")

links <- read.table(header = TRUE, text = "
startID  relation endID    
001      hasSubCat 002
001      hasSubCat 003
001      hasSubCat 004
002      hasSubCat 005
002      hasSubCat 006
002      hasSubCat 007
003      hasSubCat 008
003      hasSubCat 009
")

library(d3r)
library(dplyr)
library(igraph)

# make it an igraph
gf <- graph_from_data_frame(links[,c(1,3,2)],vertices = nodes)

# if we know that this is a tree with root as "A"
#  we can do something like this
df_tree <- dplyr::bind_rows(
  lapply(
    all_shortest_paths(gf,from="A")$res,
    function(x){data.frame(t(names(unclass(x))), stringsAsFactors=FALSE)}
  )
)

# we can discard the first column
df_tree <- df_tree[,-1]
# then make df_tree[1,1] as 1 (A)
df_tree[1,1] <- "A"

# now add node attributes to our data.frame
df_tree <- df_tree %>%
  # let's get the last non-NA in each row so we can join with nodes
  mutate(
    last_non_na = apply(df_tree, MARGIN=1, function(x){tail(na.exclude(x),1)})
  ) %>%
  # now join with nodes
  left_join(
    nodes,
    by = c("last_non_na" = "name")
  ) %>%
  # now remove last_non_na column
  select(-last_non_na)

# use d3r to nest as we would like
nested <- df_tree %>%
  d3_nest(value_cols = c("ID", "type"))

关于json - R 到使用 JSONLITE 的分层 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43399673/

相关文章:

r - 使用 geom_polygon()+coord_map() 在 ggplot 中自定义工具提示

r - 在windows下使用系统

json - 如何使用 jsonlite 将在线 JSON 数据加载到 Shiny 的应用程序?

C# JSON 解析而不是 R

json - 反序列化 Json 对象时如何转义 [] 方括号

ios - 是不是JSON解析错了?

javascript - 如何将 JSON 信息从 Flask 传递到 Angular

java - JsonArray 嵌套对象 -> Gson

r - 使用 readxl 将 excel 文件读入 R 时缺少数据框列

R 中的 JSON(使用 jsonlite)解析错误