使用 R 将关系 SQL table 转换为 JSON
Convert a relation SQL table into JSON using R
我正在尝试使用 R 将 SQL table 转换为 JSON 嵌套格式。我可以轻松地将 table 导入 R。现在的问题是获取 JSON 格式的所有父子关系。我已经设法得到某种 JSON 输出,但仅以以下形式列出所有具有各自子项的父个体:(我将仅列出 table 的前 6 行)
[
[
{
"name": ["a"],
"children": ["b"]
},
{
"name": ["b"],
"children": ["c"]
},
{
"name": ["c"],
"children": ["d"]
},
{
"name": ["b"],
"children": ["e"]
},
{
"name": ["e"],
"children": ["f"]
}
]
]
和
library(RJSONIO)
orgTable=orgTable[,c("Manager","ID")]
makeList<-function(x){
if(ncol(x)>2){
listSplit = split(x[-1],x[1],drop=T)
lapply(names(listSplit),function(y){list(name=y,children=makeList(listSplit[[y]]))})
}
else{
lapply(seq(nrow(x[1])),function(y){list(name=x[,1][y],children=x[,2][y])})
}
}
jsonOut = toJSON(list(makeList(orgTable[2:6,])),pretty=TRUE)
cat(jsonOut)
SQL table 是:
Parent Children
a b
b c
c d
b e
e f
我想得到的是这样的:
{
"name": "a",
"children": [
{
"name": "b",
"children": [
{
"name": "c",
"children": [
{
"name": "d"
}
]
},
{
"name": "e",
"children": [
{
"name": "f"
}
]
}
]
}
]
}
有人可以帮忙吗?如果可能的话,如果我也可以添加第三列的信息就完美了。
我提供的代码来自 this post,但根据我的需要稍作调整。
我对 R 还是很陌生,所以请多多包涵。
提前致谢
我将从一个简单的递归解决方案开始,它只获取 parent/children 而没有其他属性。
#get some help from igraph
library(igraph)
df <- read.table(
textConnection(
'
Parent Children
a b
b c
c d
b e
e f
' )
, header = TRUE
, stringsAsFactors = FALSE
)
el_in <- get.adjlist(graph.data.frame(df),mode="in")
# fill in name/id instead of number
el_in <- lapply(
el_in,
function(x){
names(el_in)[x]
}
)
get_children <- function( adjlist, node ){
names(Filter(function(x) x==node,unlist(el_in)))
}
recurse_tree <- function( adjlist, node = NULL ){
# start at root if undefined
# root will be the node with no in
if(is.null(node)) node <- names(Filter(function(x)length(x)==0,adjlist))
children <- get_children( adjlist, node )
if(length(children)>0){
list(
name = node
,children = lapply(
children
,function(x){
recurse_tree( adjlist, x )
}
)
)
} else {
list(
name = node
)
}
}
jsonlite::toJSON(
recurse_tree( el_in ),
auto_unbox=T
)
可能不是最有效的,但这是使用 data.tree
和 igraph
构建层次结构的解决方案。
#get some help from the relatively new data.tree
#devtools::install_github("gluc/data.tree")
library(data.tree)
#get some help from igraph
library(igraph)
df <- read.table(
textConnection(
'
Parent Children
a b
b c
c d
b e
e f
' )
, header = TRUE
, stringsAsFactors = FALSE
)
#this will be our paths for data.tree
build_path <- function(df){
g <- graph.data.frame(df)
#get an adjacency list of all in
el_in <- get.adjlist( g, mode="in" )
tree <- lapply(el_in,function(x){""})
lapply(
1:length(el_in)
,function(n){
id <- names(el_in)[n]
x <- el_in[[n]]
if(length(x)>0){
tree[[id]] <<- paste0(
tree[[el_in[[id]]]],
"/",
id
)
} else {
tree[[id]] <<- id
}
}
)
return(unlist(tree))
}
tree <- as.Node(data.frame(
pathString = build_path(df),
# have the ability to specify values
# if not then just set NA
value = NA,
stringsAsFactors = F
))
jsonlite::toJSON(
as.list( tree, mode="explicit", unname = TRUE),
auto_unbox = TRUE
)
# as a test let's build a random tree with igraph
tree_grf <- graph.tree(n=10,children=3)
plot(tree_grf)
tree <- as.Node(data.frame(
pathString = build_path(
get.data.frame(tree_grf,what="edges")
),
# have the ability to specify values
# if not then just set NA
value = NA,
stringsAsFactors = F
))
我正在尝试使用 R 将 SQL table 转换为 JSON 嵌套格式。我可以轻松地将 table 导入 R。现在的问题是获取 JSON 格式的所有父子关系。我已经设法得到某种 JSON 输出,但仅以以下形式列出所有具有各自子项的父个体:(我将仅列出 table 的前 6 行)
[
[
{
"name": ["a"],
"children": ["b"]
},
{
"name": ["b"],
"children": ["c"]
},
{
"name": ["c"],
"children": ["d"]
},
{
"name": ["b"],
"children": ["e"]
},
{
"name": ["e"],
"children": ["f"]
}
]
]
和
library(RJSONIO)
orgTable=orgTable[,c("Manager","ID")]
makeList<-function(x){
if(ncol(x)>2){
listSplit = split(x[-1],x[1],drop=T)
lapply(names(listSplit),function(y){list(name=y,children=makeList(listSplit[[y]]))})
}
else{
lapply(seq(nrow(x[1])),function(y){list(name=x[,1][y],children=x[,2][y])})
}
}
jsonOut = toJSON(list(makeList(orgTable[2:6,])),pretty=TRUE)
cat(jsonOut)
SQL table 是:
Parent Children
a b
b c
c d
b e
e f
我想得到的是这样的:
{
"name": "a",
"children": [
{
"name": "b",
"children": [
{
"name": "c",
"children": [
{
"name": "d"
}
]
},
{
"name": "e",
"children": [
{
"name": "f"
}
]
}
]
}
]
}
有人可以帮忙吗?如果可能的话,如果我也可以添加第三列的信息就完美了。
我提供的代码来自 this post,但根据我的需要稍作调整。 我对 R 还是很陌生,所以请多多包涵。
提前致谢
我将从一个简单的递归解决方案开始,它只获取 parent/children 而没有其他属性。
#get some help from igraph
library(igraph)
df <- read.table(
textConnection(
'
Parent Children
a b
b c
c d
b e
e f
' )
, header = TRUE
, stringsAsFactors = FALSE
)
el_in <- get.adjlist(graph.data.frame(df),mode="in")
# fill in name/id instead of number
el_in <- lapply(
el_in,
function(x){
names(el_in)[x]
}
)
get_children <- function( adjlist, node ){
names(Filter(function(x) x==node,unlist(el_in)))
}
recurse_tree <- function( adjlist, node = NULL ){
# start at root if undefined
# root will be the node with no in
if(is.null(node)) node <- names(Filter(function(x)length(x)==0,adjlist))
children <- get_children( adjlist, node )
if(length(children)>0){
list(
name = node
,children = lapply(
children
,function(x){
recurse_tree( adjlist, x )
}
)
)
} else {
list(
name = node
)
}
}
jsonlite::toJSON(
recurse_tree( el_in ),
auto_unbox=T
)
可能不是最有效的,但这是使用 data.tree
和 igraph
构建层次结构的解决方案。
#get some help from the relatively new data.tree
#devtools::install_github("gluc/data.tree")
library(data.tree)
#get some help from igraph
library(igraph)
df <- read.table(
textConnection(
'
Parent Children
a b
b c
c d
b e
e f
' )
, header = TRUE
, stringsAsFactors = FALSE
)
#this will be our paths for data.tree
build_path <- function(df){
g <- graph.data.frame(df)
#get an adjacency list of all in
el_in <- get.adjlist( g, mode="in" )
tree <- lapply(el_in,function(x){""})
lapply(
1:length(el_in)
,function(n){
id <- names(el_in)[n]
x <- el_in[[n]]
if(length(x)>0){
tree[[id]] <<- paste0(
tree[[el_in[[id]]]],
"/",
id
)
} else {
tree[[id]] <<- id
}
}
)
return(unlist(tree))
}
tree <- as.Node(data.frame(
pathString = build_path(df),
# have the ability to specify values
# if not then just set NA
value = NA,
stringsAsFactors = F
))
jsonlite::toJSON(
as.list( tree, mode="explicit", unname = TRUE),
auto_unbox = TRUE
)
# as a test let's build a random tree with igraph
tree_grf <- graph.tree(n=10,children=3)
plot(tree_grf)
tree <- as.Node(data.frame(
pathString = build_path(
get.data.frame(tree_grf,what="edges")
),
# have the ability to specify values
# if not then just set NA
value = NA,
stringsAsFactors = F
))